you can also give default values for arguments in terms of previous arguments. like so: (defun my-cool-func (x &optional (y (* 2 x)) (z (+ x y))) (list x y z)) CL-USER> (my-cool-func 3) => (3 6 9) CL-USER> (my-cool-func 3 2) => (3 2 5) you can do basically anything in these default-value fields. for example, if the user doesn't provide an optional value, define a new function which adds the first argument to a given input. this new function is only defined if the user does not pass the optional argument. (defun my-cool-func (x &optional (adder-func (defun my-adder-func (input) (* input x)))) (funcall adder-func x)) CL-USER> (fboundp 'my-adder-func) => NIL CL-USER> (my-cool-func 2 (lambda (input) (+ input 10))) => 12 CL-USER> (fboundp 'my-adder-func) => NIL CL-USER> (my-cool-func 2) => 4 CL-USER> (fboundp 'my-adder-func) => T
There is also the verboten &aux for some odd looks from people. :) It's a vestigial thing that makes local symbols beforehand you can SETF in the function body later.
Hello :) I was reading Practical Common Lisp and it says these about the combination of &optional with &rest: > It's possible, but rare, to use all four flavors of parameters in a single function. Whenever more than one flavor of parameter is used, they must be declared in the order I've discussed them: first the names of the required parameters, then the optional parameters, then the rest parameter, and finally the keyword parameters. Typically, however, in functions that use multiple flavors of parameters, you'll combine required parameters with one other flavor or possibly combine &optional and &rest parameters. The other two combinations, either &optional or &rest parameters combined with &key parameters, can lead to somewhat surprising behavior. So it seems that the author finds the optional/rest combination valid? (Love these brief videos by the way! Thanks! :D)
The &optional &rest combo technically works, but are there really use cases for it? Maybe if you need to operate on the first rest parameter and would like it explicitly named, you could do &optional x &rest y instead of car-ing the value from rest?
If you can just paste all the codes in the description. This is going to help us all. Great work between. Thank you. I think you shouldn't combine optional and key. Rest is safe with both.
Thanks for these videos. They are really useful! Quick question: I am reading the SICP book and it is talking about streams as an implementation of state without actually storing state in a variable (section.3.5.5) . As it is quite basic and useful is this something that is part of the core of Common Lisp? If yes what is the syntax?
I haven't read SICP yet (been on my todo list for a bunch of years now) so I'm afraid I don't know how those streams map to other similarly named concepts.
Does the order of the actual parameters matter when you have a required formal parameter mixed with some keywords? E.g. could I successfully call "(test-6 :foo 1 10 :bar 2)" and expect 10 to be bound to x?
Not quite, the order of the args after &key doesnt matter but everywhere else it does. So for test-6 (test-6 1 :foo 2 :bar 3) is legal and so is (test-6 1 :bar 2 :foo 3) but not (test-6 :foo 2 1 :bar 3) or (test-6 :foo 2 :bar 3 1) etc. I hope this helps
I haven't used it so I can't say yet. Racket's language systems look awesome though. I do like my unhygienic macros but they have something pretty special. I'd stick with cl just for the performance though, sbcl is a beast..and you can get down to the assembly level which is amazing.
@@CBaggers I wish you would do one or more videos regarding the latter statement in your comment (sbcl being a beast and getting down to assembly level). All your videos are extremely interesting.
Great video, although I'd like to point out that the behaviour of &optional together with &rest is defined. Namely optional chomps up extra arguments and all arguments that are not used by required arguments or &optional arguments are passed on to &rest.
Thanks for this great tutorial, I am trying to follow your instruction of the following code: #+BEGIN_SRC elisp (defun test-0 (x &optional (y 0)) (+ x y)) #+END_SRC But I also get this: #+BEGIN_SRC elisp Debugger entered--Lisp error: (error "Malformed arglist: (x &optional (y 0))") signal(error ("Malformed arglist: (x &optional (y 0))")) error("Malformed arglist: %s" (x &optional (y 0))) #f(compiled-function (name arglist &optional docstring decl &rest body) "Define NAME as a function. The definition is (lambda ARGLIST [DOCSTRING] BODY...). See also the function `interactive'. DECL is a declaration, optional, of the form (declare DECLS...) where DECLS is a list of elements of the form (PROP . VALUES). These are interpreted according to `defun-declarations-alist'. The return value is undefined." #)(test-0 (x &optional (y 0)) (+ x y)) macroexpand((defun test-0 (x &optional (y 0)) (+ x y)) nil) macroexp-macroexpand((defun test-0 (x &optional (y 0)) (+ x y)) nil) macroexp--expand-all((defun test-0 (x &optional (y 0)) (+ x y))) macroexpand-all((defun test-0 (x &optional (y 0)) (+ x y))) eval-sexp-add-defvars((defun test-0 (x &optional (y 0)) (+ x y))) elisp--eval-last-sexp(nil) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) call-interactively(eval-last-sexp nil nil) command-execute(eval-last-sexp) #+END_SRC I think my code is the same as yours, not sure why this happen on my machine: ~GNU Emacs 26.1 (build 1, x86_64-w64-mingw32) of 2018-05-30~
ELisp is emacs lisp, my videos are all for common lisp so most of the knowledge is not portable. There is a library for emacs that provides a lot of the common lisp constructs though www.gnu.org/software/emacs/manual/html_node/cl/Argument-Lists.html
Ditto on the praising the format. It helps to have the bite size break down of the topics, and your explanations are clear. Thanks.
you can also give default values for arguments in terms of previous arguments. like so:
(defun my-cool-func (x &optional (y (* 2 x)) (z (+ x y)))
(list x y z))
CL-USER> (my-cool-func 3)
=>
(3 6 9)
CL-USER> (my-cool-func 3 2)
=>
(3 2 5)
you can do basically anything in these default-value fields.
for example, if the user doesn't provide an optional value, define a new function which adds the first argument to a given input.
this new function is only defined if the user does not pass the optional argument.
(defun my-cool-func (x &optional (adder-func (defun my-adder-func (input) (* input x))))
(funcall adder-func x))
CL-USER> (fboundp 'my-adder-func)
=>
NIL
CL-USER> (my-cool-func 2 (lambda (input) (+ input 10)))
=>
12
CL-USER> (fboundp 'my-adder-func)
=>
NIL
CL-USER> (my-cool-func 2)
=>
4
CL-USER> (fboundp 'my-adder-func)
=>
T
This is a great series - Very well explained and presented. As someone who is learning CL, I really appreciate these vids man!
That is fantastic to hear! I was wondering whether this format would work for people, I'll definitely keep making them then.
There is also the verboten &aux for some odd looks from people. :) It's a vestigial thing that makes local symbols beforehand you can SETF in the function body later.
Really appreciate these videos!
Awesome! Thanks for checking them out
Hello :) I was reading Practical Common Lisp and it says these about the combination of &optional with &rest:
> It's possible, but rare, to use all four flavors of parameters in a single function. Whenever more than one flavor of parameter is used, they must be declared in the order I've discussed them: first the names of the required parameters, then the optional parameters, then the rest parameter, and finally the keyword parameters. Typically, however, in functions that use multiple flavors of parameters, you'll combine required parameters with one other flavor or possibly combine &optional and &rest parameters. The other two combinations, either &optional or &rest parameters combined with &key parameters, can lead to somewhat surprising behavior.
So it seems that the author finds the optional/rest combination valid?
(Love these brief videos by the way! Thanks! :D)
The &optional &rest combo technically works, but are there really use cases for it?
Maybe if you need to operate on the first rest parameter and would like it explicitly named, you could do &optional x &rest y instead of car-ing the value from rest?
great video ! please make video about reader macro :)
Sounds fun! I'm not sure when but we will get to it eventually
thank you, FINALLY i understand it! :D
If you can just paste all the codes in the description. This is going to help us all. Great work between. Thank you. I think you shouldn't combine optional and key. Rest is safe with both.
Thanks for these videos. They are really useful! Quick question: I am reading the SICP book and it is talking about streams as an implementation of state without actually storing state in a variable (section.3.5.5) . As it is quite basic and useful is this something that is part of the core of Common Lisp? If yes what is the syntax?
I haven't read SICP yet (been on my todo list for a bunch of years now) so I'm afraid I don't know how those streams map to other similarly named concepts.
Does the order of the actual parameters matter when you have a required formal parameter mixed with some keywords? E.g. could I successfully call "(test-6 :foo 1 10 :bar 2)" and expect 10 to be bound to x?
Not quite, the order of the args after &key doesnt matter but everywhere else it does. So for test-6 (test-6 1 :foo 2 :bar 3) is legal and so is (test-6 1 :bar 2 :foo 3) but not (test-6 :foo 2 1 :bar 3) or (test-6 :foo 2 :bar 3 1) etc. I hope this helps
Hey Baggers, you probably get this question a lot, but here it is again. What do you think about scheme?
I haven't used it so I can't say yet. Racket's language systems look awesome though. I do like my unhygienic macros but they have something pretty special. I'd stick with cl just for the performance though, sbcl is a beast..and you can get down to the assembly level which is amazing.
@@CBaggers I wish you would do one or more videos regarding the latter statement in your comment (sbcl being a beast and getting down to assembly level). All your videos are extremely interesting.
Great video, although I'd like to point out that the behaviour of &optional together with &rest is defined. Namely optional chomps up extra arguments and all arguments that are not used by required arguments or &optional arguments are passed on to &rest.
Oh thanks! I need to go read the spec again
Thanks for this great tutorial, I am trying to follow your
instruction of the following code:
#+BEGIN_SRC elisp
(defun test-0 (x &optional (y 0))
(+ x y))
#+END_SRC
But I also get this:
#+BEGIN_SRC elisp
Debugger entered--Lisp error: (error "Malformed arglist: (x &optional (y 0))")
signal(error ("Malformed arglist: (x &optional (y 0))"))
error("Malformed arglist: %s" (x &optional (y 0)))
#f(compiled-function (name arglist &optional docstring decl &rest body) "Define NAME as a function.
The definition is (lambda ARGLIST [DOCSTRING] BODY...).
See also the function `interactive'.
DECL is a declaration, optional, of the form (declare DECLS...) where
DECLS is a list of elements of the form (PROP . VALUES). These are
interpreted according to `defun-declarations-alist'.
The return value is undefined." #)(test-0 (x &optional (y 0)) (+ x y))
macroexpand((defun test-0 (x &optional (y 0)) (+ x y)) nil)
macroexp-macroexpand((defun test-0 (x &optional (y 0)) (+ x y)) nil)
macroexp--expand-all((defun test-0 (x &optional (y 0)) (+ x y)))
macroexpand-all((defun test-0 (x &optional (y 0)) (+ x y)))
eval-sexp-add-defvars((defun test-0 (x &optional (y 0)) (+ x y)))
elisp--eval-last-sexp(nil)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)
#+END_SRC
I think my code is the same as yours, not sure why this happen on
my machine: ~GNU Emacs 26.1 (build 1, x86_64-w64-mingw32) of
2018-05-30~
ELisp is emacs lisp, my videos are all for common lisp so most of the knowledge is not portable. There is a library for emacs that provides a lot of the common lisp constructs though www.gnu.org/software/emacs/manual/html_node/cl/Argument-Lists.html