Does any Common Lisp function return 3 values? - return-value

Does any Common Lisp (builtin) function return more than 2 values? I know many that return 2, but I can't think of one that returns 3.
(I saw a comment here about returning more than 2 values, and tried to think of a case where CL did this, but can't.)

Yes, such functions exist. Here is the complete list of functions in the COMMON-LISP package that return exactly three values, as declared in SBCL source code:
COMPILE required: 3, optional: 0, rest?: NIL
INTEGER-DECODE-FLOAT required: 3, optional: 0, rest?: NIL
COMPILE-FILE required: 3, optional: 0, rest?: NIL
GET-PROPERTIES required: 3, optional: 0, rest?: NIL
FUNCTION-LAMBDA-EXPRESSION required: 3, optional: 0, rest?: NIL
DECODE-FLOAT required: 3, optional: 0, rest?: NIL
RENAME-FILE required: 3, optional: 0, rest?: NIL
In addition, the following functions return a constant number of values greater than three:
DECODE-UNIVERSAL-TIME required: 9, optional: 0, rest?: NIL
GET-DECODED-TIME required: 9, optional: 0, rest?: NIL
These functions return a variable number of values, hence possibly more than three:
NO-APPLICABLE-METHOD required: 0, optional: 0, rest?: T
NO-NEXT-METHOD required: 0, optional: 0, rest?: T
VALUES required: 0, optional: 0, rest?: T
(I've omitted some functions from this list where SBCL does not declare
a values type explicitly. get-setf-expansion is one of them.)
Explanations of the columns: required is minimum number of return values for these functions, optional a fixed number of return values which SBCL thinks might or might not be returned, rest? indicates that a variable number of values is expected. (Only macroexpand and macroexpand-1 actually use &optional, don't ask me why.)
And just for fun, here is the source code I used to come up with these tables:
(do-external-symbols (sym :common-lisp)
(when (fboundp sym)
(multiple-value-bind (required optional rest)
(let ((fun-type (sb-int:info :function :type sym)))
(etypecase fun-type
(sb-kernel:fun-type
(let ((returns
(sb-kernel:fun-type-returns fun-type)))
(etypecase returns
(sb-kernel:values-type
(values (length (sb-kernel:values-type-required returns))
(length (sb-kernel:values-type-optional returns))
(sb-kernel:values-type-rest returns)))
(sb-kernel:named-type
(if (sb-kernel:named-type-name returns)
(values 1 0 t)
(values 0 0 nil))))))
(t
(values 0 0 t))))
(format t
"~A~40Trequired: ~D, optional: ~D, rest?: ~A~%"
sym
required optional rest))))

decode-universal-time returns nine values.

There is a get-setf-expansion function. It returns 5 values.

VALUES and VALUES-LIST, among others.

Related

Define if numbers in list are less than one in parameter - Scala

Write a function which at the input takes two parameters: a list of integers and a number.
The output returns a logical value.
The function returns "true" if all numbers in the list are smaller than the number given in the second parameter. Otherwise, the function returns "false".
My code:
def less [A](list:List[A], number:Int):Boolean =
if (list == Nil) false
else ((List.head < number) && less[A](list:List.tail, number:Int))
less(List(1, 2, 3, 4), 5)
less(List(6,1,2,3),6)
Error message in IntelliJ:
On line 3: error: value head is not a member of object List
else (List.head < number) && less[A](list:List.tail, number:Int) //2
^
On line 3: error: type tail is not a member of object List
My question: What should I improve in this code to have it working?
Seems an awful lot like home work...
Scala has a forall function that can test a predicate against all values in the collection and returns a Boolean.
def less(xs: List[Int], number: Int) = xs.forall(x => ???)
I think you want something like this:
def less (list:List[Int], number:Int):Boolean =
if (list == Nil) true
else ((list.head < number) && less(list.tail, number))
less(List(1, 2, 3, 4), 5)//true
less(List(6,1,2,3),6)//false
But you should just use forall like #Brian said

Clojure backtick expansion

According to the Learning Clojure wikibook backticks are expanded as follows
`(x1 x2 x3 ... xn)
is interpreted to mean
(clojure.core/seq (clojure.core/concat |x1| |x2| |x3| ... |xn|))
Why wrap concat with seq? What difference does it make?
Regardless of how it arose
concat returns a sequence, and
seq returns a sequence with the same content as its sequence argument,
... so seq is effectively an identity-op on a concat... except in one circumstance:
When s is an empty sequence, (seq s) is nil.
I doubt that the expansion is correct, since
`()
... evaluates to
()
... with type
clojure.lang.PersistentList$EmptyList
Whereas
(seq (concat))
... evaluates to
nil
This suggests that the wrapping call to seq is not there.
Strictly speaking, it expands to:
(macroexpand '`(x1 x2 x3))
(clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/x1)) (clojure.core/list (quote user/x2)) (clojure.core/list (quote user/x3))))
(macroexpand `(x1 x2 x3))
(user/x1 user/x2 user/x3)
Why the call seq ? Because sequences are corner stones in Clojure philosophy. I recommend you read Clojure Sequences. Otherwise, I would duplicate it here.

Pass a data structure in to a macro for filling in

I'm trying to solve a problem: I need to create a map from passed-in values, but while the symbol names for the values are consistent, the keys they map to are not. For instance: I might be passed a value that is a user ID. In the code, I can always use the symbol user-id -- but depending on other factors, I might need to make a map {"userId" user-id} or {"user_id" user-id} or {:user-id user-id} or -- well, you get the picture.
I can write a macro that gets me part-way there:
(defmacro user1 [user-id] `{"userId" ~user-id}
(defmacro user2 [user-id] `{"user_id" ~user-id}
But what I'd much rather do is define a set of maps, then combine them with a given set of symbols:
(def user-id-map-1 `{"userId" `user-id}
(defn combiner [m user-id] m) ;; <-- Around here, a miracle occurs.
I can't figure out how to get this evaluation to occur. It seems like I should be able to make a map containing un-evaluated symbols, then look up those symbols in the lexical scope of a function or macro that binds those symbols as locals -- but how?
Instead of standardizing your symbolic names, use maps with standard keyword keys. You don't need to go near macros, and you can turn your maps into records if need be without much trouble.
What you know as
(def user1 {:id 3124, :surname "Adabolo", :forenames ["Julia" "Frances"]})
... can be transformed by mapping the keys with whatever function you choose:
(defn map-keys [keymap m]
(zipmap (map keymap (keys m)) (vals m)))
For example,
(map-keys name user1)
;{"id" 3124, "surname" "Adabolo", "forenames" ["Julia" "Frances"]}
or
(map-keys {:id :user-id, :surname :family-name} user1)
;{:user-id 3124, :family-name "Adabolo", nil ["Julia" "Frances"]}
If you want rid of the nil entry, wrap the expression in (dissoc ... nil):
(defn map-keys [keymap m]
(dissoc
(zipmap (map keymap (keys m)) (vals m))
nil))
Then
(map-keys {:id :user-id, :surname :family-name} user1)
;{:user-id 3124, :family-name "Adabolo"}
I see from MichaƂ Marczyk's answer, which has priority, that the above essentially rewrites clojure.set/rename-keys, which, however ...
leaves missing keys untouched:
For example,
(clojure.set/rename-keys user1 {:id :user-id, :surname :family-name})
;{:user-id 3124, :forenames ["Julia" "Frances"], :family-name "Adabolo"}
doesn't work with normal functions:
For example,
(clojure.set/rename-keys user1 name)
;IllegalArgumentException Don't know how to create ISeq from: clojure.core$name ...
If you forego the use of false and nil as keys, you can leave missing keys untouched and still use normal functions:
(defn map-keys [keymap m]
(zipmap (map #(or (keymap %) %) (keys m)) (vals m)))
Then
(map-keys {:id :user-id, :surname :family-name} user1)
;{:user-id 3124, :family-name "Adabolo", :forenames ["Julia" "Frances"]}
How about putting your passed-in values in a map keyed by keywords forged from the formal parameter names:
(defmacro zipfn [map-name arglist & body]
`(fn ~arglist
(let [~map-name (zipmap ~(mapv keyword arglist) ~arglist)]
~#body)))
Example of use:
((zipfn argmap [x y z]
argmap)
1 2 3)
;= {:z 3, :y 2, :x 1}
Better yet, don't use macros:
;; could take varargs for ks (though it would then need another name)
(defn curried-zipmap [ks]
#(zipmap ks %))
((curried-zipmap [:x :y :z]) [1 2 3])
;= {:z 3, :y 2, :x 1}
Then you could rekey this map using clojure.set/rename-keys:
(clojure.set/rename-keys {:z 3, :y 2, :x 1} {:z "z" :y "y" :x "x"})
;= {"x" 1, "z" 3, "y" 2}
The second map here is the "translation map" for the keys; you can construct in by merging maps like {:x "x"} describing how the individual keys ought to be renamed.
For the problem you described I can't find a reason to use macros.
I'd recommend something like
(defn assoc-user-id
[m user-id other-factors]
(assoc m (key-for other-factors) user-id))
Where you implement key-for so that it selects the key based on other-factors.

Reading the syntax off of this listing at scala-lang

Just learning some basic stuff here.
It appears the count method for Vector will be useful to me for an exercise I'm working on, but from reading its entry at scala-lang I'm having a hard time understanding exactly how to use it, syntactically speaking.
Here's what the entry says:
count(p: (A) => Boolean): Int
I think that's supposed to be telling me the syntax to use when calling the method.
It tells me that "p" is the predicate to be satisfied. Okay, I know what a predicate is in the abstact. What does a predicate look like in Scala though?
Then there's a colon. Do I type that? Or is this meta-linguistic notation of some kind?
Then there's a rocket. Okay. Then that word Boolean--but what is it doing there? I assume I don't literally type "Boolean." (Do I?)
Anyway, hopefully you see my problem(s).
How does this work?
You are almost there!
count needs a parameter p of type (:) A to (rocket) Boolean, where 'A' is the type of elements stored by the vector. So you have to provide a function from A to Boolean.
So you can use it like this:
val v = Vector(1, 2, 3, 4, 5, 6) // == Vector[Int](1, 2, 3, 4, 5, 6)
def odd(elem: Int): Boolean = {
elem % 2 == 0
}
v.count(odd) // == 3
Or using some syntactic sugar:
val v = Vector(1, 2, 3, 4, 5, 6) // == Vector[Int](1, 2, 3, 4, 5, 6)
v.count(_ % 2 == 0) // == 3

Why (list + 1 2) evaluates to ('(+ 1 2) 1 2) in Common Lisp

Why does evaluating (list + 1 2) in Common Lisp (CCL REPL) returns ('(+ 1 2) 1 2)?
More: OK, I see that + actually evaluates to the last REPL result, but I still have a question: Is this a standard CL REPL thing, to have + equal to the last result, or is it Clozure specific?
You will find that, in the REPL, the variable * holds the last result, and + holds the last evaluated form.
For example:
> (+ 1 2)
=> 3
> +
=> (+ 1 2)
> (+ 2 3)
=> 5
> *
=> 5
Yes, these are standard, and in the HyperSpec.
If you wish to create a list containing the symbol +, rather than its value, you will need to quote it, as such: '+, or (quote +).