3 ms·
I don't think this is what enduser means. Lisp is the only language i know of where you can run a function such as (defun foo () (progn (format t "~a~%"
by Munksgaard 13y ago
I don't think this is what enduser means. Lisp is the only language i know of where you can run a function such as
(defun foo ()
(progn (format t "~a~%" (read-line))
(foo)))
and then, while it is recursing, change the function to
(defun foo ()
(progn (format t "~a and john~%" (read-line))
(foo)))
recompile it, and have the behavior of your program change, while it is running. This is part of what makes lisp excellent for rapid prototyping. I'd give more examples, but I'm lazy, and it's been properly described elsewhere.
- Groxx 13y agoSeems pretty simple to me in Ruby. $ irb >> def go > puts "what" > debugger > go > end >> go "what" # stops on debugger line >> Object.module_eval "def go; puts 'wat'; end" >> continue "wat" There are of course other ways to do that, I just picked a simple one. You can break at lines / statements in files, so you don't need to include that "debugger" line. You can do something other than Object.module_eval. You can use something like Pry that would make this simpler and give you in-line source code, even after editing (IIRC). You can use something like Hijack to modify any running Ruby process - when you disconnect, your modified code will still be running. Lisp is not special in what it is capable of. Period. It's special because a) it's very old, and b) it's tuned for these features, in its own unique, minimalistic way. Yes, not all languages can do this (though you can do crazy things with GDB / debuggers in general, including using it as a REPL for compiled languages (really! it's not hard!)). But Lisp / the Lisp family are not even remotely the only ones which can.
- Munksgaard 13y agoThat is indeed very handy, but I would argue that there's a difference between running a program in a debugger and running it normally. With regards to the rest of your post: macros and data-as-code. Have you read this http://www.paulgraham.com/diff.html http://www.paulgraham.com/diff.html ?
- Groxx 13y ago"What Made Lisp Different" - all true. All intended as past tense. I never see claims that Lisp is unique because it has GC, for instance. Looking at the 'setf' macro, since you have to use 'defsetf', I don't see the difference between that and something in Ruby where you could do (errors aside): class Object def defsetf(name) $setf[self.class] = name end end def setf(class, *args) class.send($setf[class], *args) end class Whatever defsetf :set_something def set_something; end end # elsewhere... setf Whatever, instance, value Adding arbitrarily-complex ways to let you specify how to transform the arguments to a call is as easy as accepting a lambda instead of a symbol, recursive setf-ing[1] is just a lookup on the arguments and then nesting lambdas. I might be missing some deeper realization here though - defsetf seems pretty simple. Certainly the use could be complex, but I see nothing that implies that its implementation is unachievable, even with nearly-identical syntax, so what remains is library support and community. Again - specialization, not unique attribute of the language. As to "data-as-code", I think you mean the other way around? If not, eval. If yes, Ruby's reflection is I think insufficient without heavy modification like e.g. running a ruby interpreter in ruby to read its own source code and "reflect" with the AST that generates (though this is possible[2]). This is one spot where Lisp-likes certainly excel to a degree few outsiders achieve, but I'm sure I've seen outsiders, they're just not as fluent or efficient at running it. But few outsiders have real interest in optimizing it, or people label them as yet another Lisp-like, making the point sort of moot since it's part of the definition of being Lisp-like (to many). -- Macros in particular come up often, but I don't see anything really interesting about them. If you have the full AST available (a rarity, I'll admit), then it seems like a strict subset of runtime modification - it's just a self-eliminating runtime modification, done ahead of time for speed purposes. Except for maybe C-style macros, which (via a horrible syntax) can generate anything, not just valid code, which isn't always possible. [1]: (setf (sqrt something) number) => (set-sqrt something number) => (setf something (* number number)) in here: http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.h... found via here: http://stackoverflow.com/questions/267862/what-makes-lisp-macros-so-special http://stackoverflow.com/questions/267862/what-makes-lisp-ma... [2]: https://www.ruby-forum.com/topic/1108988 https://www.ruby-forum.com/topic/1108988