Skip to content

Various Comments on CL

Ashok Khanna edited this page Nov 3, 2021 · 5 revisions

[AK] When working with very idiosyncratic code, its fine to condense and avoid using too many helper functions as it makes it easier to read if everything in one place. This likely makes the code look more procedural in nature, sort of like a "recipe". See save-test in parachute-repo

[PJB] There's a convention that single-word predicates use p as suffix and multi-word predicates use -p. But if the predicate name is itself prefixed, we don't modify it with a -p, e.g. string-lessp (it's not like we test for things that should be string-lesses)

(defun test (&key (df #'car)) (funcall df '(1 2 3))) lisp123_ So I did the above lisp123_ is there a reason I didn't have to #' the df? lisp123_ Is the first argument of funcall always evaluated to its function object? lisp123_ CLHS says so :) So above can be ignored thrig #'df would presumably call a df defun, which presumably you don't want here lisp123_ thrig: you are right lisp123_ thanks, thats a good nuance to know thrig has left IRC (Remote host closed the connection) pjb lisp123_: it's really easy: in CL, a name (a symbol) can designate two different things: variables or functions. pjb lisp123_: (actually, it can also designate more, like blocks, tags, types, anything). But for CL, variables and functions are the basis. pjb lisp123_: when you evaluate foo alone, it's taken as the name of a variable foo. pjb lisp123_: when you want to get the function named foo, you need to use (function foo) (abbreviated as #'foo). lisp123_ pjb: How does df work in the above? Is it a symbol? lisp123_ (can I give it a variable value and also a function value)? pjb lisp123_: now, what is df? It's the name of a parameter variables. Therefore when you evaluate df, you get the value of that variable, which is the result of #'car aka (function car), which is the function named car. pjb df is a symbol. pjb lisp123_: assuming you didn't played with read-base. lisp123_ For example, this doesn't work: (defun test (&key (df #'car)) (funcall #'df '(1 2 3))) pjb lisp123_: if you set read-base to an integer greater than 15., then df would be read as an integer. pjb lisp123_: no, because here, (function df) tries to find a function named df. pjb But you defined no function with the name df. pjb You only defined a paremeter variable named df. pjb (defun df (x) 'outer) pjb (defun test-1 (&key (df #'car)) (funcall #'df '(1 2 3))) (test-1) #| --> outer |# pjb (defun test-2 (&key (df #'car)) (funcall df '(1 2 3))) (test-2) #| --> 1 |# selwyn has joined (~selwyn@user/selwyn) lisp123_ (defun test (&key (df #'car)) (setf df 55) (funcall #'df '(1 2 3))) lisp123_ What about this (above)? tyson2 has left IRC (Quit: ERC (IRC client for Emacs 27.2)) pjb This would still call the function named df. lisp123_ I thought if df is a symbol, it can have both a variable value and a function value pjb The variable named df is irrelevant in that funcall. lisp123_ oh soryr lisp123_ my mistake lisp123_ Try without the #' in front of df pjb lisp123_: a symbol has indeed a symbol-function and a symbol-value, but this is something else (but related). lisp123_ "Value of DF in (SB-KERNEL:%COERCE-CALLABLE-FOR-CALL DF) is 55) pjb lisp123_: when the variable is a lexical variable, then it's unrelated to the symbol-value. lisp123_ pjb: so a lexical variable only has one "value", which can be either a variable or a symbol? pjb lisp123_: when the variable is a dynamic variable, then the value of the variable is "stored" in the symbol-value of the symbol naming the variable. pjb lisp123_: but it's a little more complicated, with threads, since each threads can have it's onw dynamic variable, hence it's own symbol-value for the same symbol. pjb lisp123_: the error without the code doesn't mean anything. Try http://ideone.com lisp123_ pjb: thanks lisp123_ I got it now. We need #' for dynamic symbols because it can have two values, a variable & a function (which must be set via defun, not simply (setf df #'car) lisp123_ Whereas for lexical variables, there is only one value associated with the variable lisp123_ So #' is not meant to be done (since that looks up the global environment) pjb lisp123_: check this: https://ideone.com/AW0nMJ pjb no, #' is underlated to dynamic variables named by special symbols. pjb We need quote because lisp is homoiconic, to distinguish the case when you want a literal symbol, instead of a variable. pjb We need function because Common Lisp is a lisp-2, to distinguish the case when x names a function, instead of x naming a variable. mfiano (defun foo () (print :foo)) (flet ((foo () (print :bar))) (funcall 'foo) (funcall #'foo)) lisp123_ Thanks pjb lisp123_: in addition symbols can designate a function. mfiano The first call uses indirection to refer to the local function. pjb when we do (funcall 'foo), funcall iw use (fdefinition 'foo) to get the function object. For symbols, fdefinition return the (symbol-function 'foo) lisp123_ pjb & mfiano - thanks I get understand now :) mfiano err the function in thje global environment pjb lisp123_: this will be the same as (function foo), UNLESS you have a local function definition named foo, in which case (function foo) will return the local function! pjb Hence the difference between (funcall 'foo) and (funcall #'foo): without local function foo, it's the same, with a local function foo it's different. lisp123_ pjb: oooo now that's very interesting mfiano Try my example and try to see why it prints two different things 22:57 pjb lisp123_: now, where there may be some confusion, is in function calls: (defun foo (x) (* x 2)) (let ((foo 21)) (foo foo)) lisp123_ Let me save that down for future reference pjb lisp123_: in (foo foo), the first foo names a function, and the second foo names a variable. pjb lisp123_: this is the rule for function calls. lisp123_ mfiano: Thanks, I tried it, but I only get it now, I didn't read through carefully the first time I looked at the output pjb lisp123_: note in (block foo (tagbody foo (if (foo foo) (go foo) (return-from foo 42))))

there 4 different things named foo: a block, a tag, a function and a variable. pjb lisp123_: you can invent new name spaces. You only need to provide an operator such as function to map symbols to objects.

[Aflr] Use print-length and print-level to control how much of a list is PRINTED

Clone this wiki locally