9 ms·
Common Lisp doesn't have type checking and well defined namespace. And it has eval. That's certainly a no go for people like me. Most programmers in the world
by euske 10y ago
Common Lisp doesn't have type checking and well defined namespace. And it has eval. That's certainly a no go for people like me.
Most programmers in the world don't have to invent/implement a radical new idea in five minutes.
- adwf 10y agoEval? The entire point of Lisp macros is toying around with evalulation in a safe fashion. It's other languages that do it so dangerously that gives eval a bad name. Lisp is the shining example of how to do it right.
- chvid 10y agoAFAIK macros in Lisp are turing complete and executed at compile time. This means (in principle) that there is no guarantee that a Lisp compile will ever terminate. I don't know why the OP is been down voted. Lisp is not for everyone and every application; I think that is a perfectly reasonable point of view.
- pjc50 10y agoC++ templates are also turing complete, executed at compile time, and can result in extremely high compile times: http://cpptruths.blogspot.co.uk/2005/11/c-templates-are-turing-complete.html http://cpptruths.blogspot.co.uk/2005/11/c-templates-are-turi... I don't think that failure to terminate compiles is too big a problem in practice; treat it as just another form of compile-time error and fix your program.
- klibertp 10y agoThe OP is being downvoted because he lies. Common Lisp does have strong and optional static typing. It does have namespaces. As for CL having `eval` - well, this is true at least. But I fail to see how in the world could that be a bad thing...
- chvid 10y agoIf a language has an eval construct it is hard/impossible to reason about types, security and correctness. It also makes it hard to compile it to machine code.
- adwf 10y agoThat would be true if we were talking about normal languages eval'ing strings. Lisp on the other hand treats the code as data and has the full compiler available at runtime. It can check types at both runtime and compile time, and it will still compile it down to nice machine code on the fly. Lisp eval is not the same as other languages, you use it implicitly all the time. Any occurence of macros or something like `(1 ,(+ 2 3) 4) is playing around with evaluation behind the scenes.
- chvid 10y agoParsing Lisp is not so hard, but as you said. It requires a JIT compiler or an interpreter. There are still some platforms/scenarios where that is not wanted.
- sklogic 10y agosbcl has `eval`, but it does not have a JIT compiler or an interpreter.
- sklogic 10y agoMacros do not need to be implemented with eval, unless they're lexically scoped macros. They're just normal function, normally complied just like anything else. What is important is an incremental compilation, one top level statement at a time.
- _ph_ 10y agoIt is even better. Common Lisp macros are not a special macro language, but rather plain Lisp functions, which are run at compile time. This is important, because it means, you can write proper code in your development language for macro expansion instead of some obscure macro expansion language. This makes the process of writing macros rather robust and of course powerful. But of course, this means that like any program you write, you cannot guarantee that they terminate. For real-life macros that is rather a non-issue as they usually contain just a rather few lines of mostly simple code.
- sklogic 10y agoI don't even remember when was the last time I saw eval being used outside of the macros. And the latter is also quite a specific and rare use case.
- _ph_ 10y agoAnd I don't remember when I saw an "eval" used inside a macro either. There are almost no reasons to use "eval" in any Common Lisp program.
- sklogic 10y agoA use case for eval inside a macro is, for example, when you want to evaluate into a constant some part of a code constructed by this macro, but you do not want to do macro staging for whatever reason. I only did it a couple of times.
- tempodox 10y agoI take it, you don't use JavaScript, then? What do you mean with “well defined namespace”?
- _ph_ 10y agoCommon Lisp both has strong dynamic type checking as well as optional static type checking. For example, you can declare the static types of function parameters and the return results. For a good compiler using static type declarations, look at SBCL, which makes excellent use of type information to get up to C like performance of the compiled code. It also is very good about type inferencing. So if it knows the input types for a function call, it usually can infer the function result type and use that for further type reasoning. Common Lisp of course has defined name spaces. They are called packages. Yes it has eval, but I have not seen a Lisp program in years which used it. And it would be easy to lint programs so it is not used, if you had a reason to be afraid of it.
- muflax 10y agoHow does static type checking work in CL? One of the most important use cases for static typing is safe modification of existing code, like during refactoring. So a typical example: I have some struct with a field of one type, say a string. I use it in a few functions, reading and writing it. Now I change the field to a different type, say an array of strings instead. I want the compiler to tell me about all the code that's now invalid. How do I do that? I quickly wrote up a simple example of the (statically) untyped code I mentioned: http://pastebin.com/f7KWETvT http://pastebin.com/f7KWETvT (I can also write a matching example in some common static language (like C or ML), but I think it's clear what I mean.) What type annotations do I add to make that basic use case work? So what do I add such that it first type-checks when name is just a string, then change the annotation to make name an array of strings, and get two compile-time errors because the functions are now wrong. (Unfortunately, I only know a little bit of CL (and even then mostly due to familiarity with Emacs Lisp), so my example might be a bit un-idiomatic. Feel free to turn it into idiomatic CL if something is too weird!)
- _ph_ 10y agoIf you wanted to define a type-safe person struct, you could do it with: (defstruct person (age 0 :type fixnum) (name "" :type string)) Now every access to that person structure should be checked by the compiler. You can create a person like: (setf p (make-person :age 7 :name "fred")) => #S(PERSON :AGE 7 :NAME "fred") But not with: (setf p (make-person :age 7 :name 8)) which causes SBCL to error with: The value 8 is not of type STRING. [Condition of type TYPE-ERROR] Equally, if you tried wrongly to define (defun print-hello (person) (let ((name (string-upcase (person-age person)))) (format t "Hallo ~a!~%" name))) You get at least a warning you should heed: ; caught WARNING: ; Asserted type (OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL CHARACTER) ; conflicts with derived type (VALUES FIXNUM &OPTIONAL). So, for refactoring, you would change the type signatures of your struct and then recompile all code to see whether the compiler generates errors/warnings.
- euske 10y agoLate edit: Sorry, I meant that CL doesn't have a well defined scope, not a namespace.