5 ms·
> ((if (< 1 0) + ) 42 100) This gives me an error in SBCL. Error below: ; in: (IF (< 1 0) ; + ; *) 42 ; ((IF (< 1 0) ; + ;
by eminent101 4y ago
> ((if (< 1 0) + ) 42 100)
This gives me an error in SBCL. Error below:
; in: (IF (< 1 0)
; +
; *) 42
; ((IF (< 1 0)
; +
; *)
; 42 100)
;
; caught ERROR:
; illegal function call
;
; compilation unit finished
; caught 1 ERROR condition
Why does it not work and how to make it work?
- moonchild 4y agoCommon lisp has separate function and value namespaces, unlike scheme. Try (funcall (if (< 1 0) #'+ #'*) 42 100).
- jlg23 4y agoSee moonchild's response for the why, here is the how: (funcall (if (< 1 0) #'+ #'*) 42 100) Edit: this is actually a pretty famous interview question for lisp jobs: write a program that is valid in CL and in scheme but produces different output. The solution is always to use the fact that scheme is a lisp-1, i.e. it has ONE namespace for variables and functions) and CL is a lisp-2, with TWO distinct namespaces.
- sph 4y agoFinding out about lisp-1 and lisp-2 when hacking in elisp turned me off so much I've decided to write my own editor in Scheme. This is my personal crusade for the next X months.
- nerdponx 4y agoHow about using Neovim and writing scripts and configs in Fennel? https://fennel-lang.org/ https://fennel-lang.org/
- sph 4y agovim is great but Emacs is on a whole other level for me. But I would love to spend some time to write a löve2d game in Fennel, for sure.
- jlg23 4y agoI have yet to find a use-case where I really want a lisp-1 over a lisp-2. Though I'd really love to see some production code that exploits the single namespace.
- Kamq 4y agoIt's kinda nice when you want to, say, name a list "list" despite there being a list function. But I agree, it isn't super important.
- Zambyte 4y agoI think you have it backwards. That's why you'd want a Lisp-2 over a Lisp-1.
- Kamq 4y agoThat's what I was describing, yes.
- kazinator 4y agoThe thing is that Lisp-1 doesn't prevent you from naming a variable lisp; you may then have a problem if you try to use the list function in the same scope. It is a very important issue, because it interacts with hygiene in the face of macros. Lisp-1 dialects, and more broadly, single namespace languages, require hygienic macros if they have a macro system. Hygienic macros systems are gross; not everyone likes their complexity. They have referential transparency comes at the cost of sacrificing implementation transparency. A user of a Lisp-2 language can pretend that hygienic macros don['t exist, and be happy for the rest of their days. The reason is that if you do this in a Lisp-2, you're safe: (let ((list '(1 2 3)) (opaque-macro list)) Suppose opaque-macro has an expansion which contains (list ...) calls. Those are unaffected by the variable. opaque-macro would cause a problem if it tried to bind a variable called list. That is taken care of in unhygienic macro programming by using explicit gensyms. There could be a problem if there was a list variable that opaque-macro's expansion depends on. For that we have (1) nameing conventions like *list* for varaibles and (2) package system: macros coming from a foobar library, such that the variable they reference is foobar::list, unrelated to the user's (let ((list ...))). The whole Lisp-2 + unnhygienic macros (+ packages) is easy to work with and understand, simple and pragmatic.