Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

Common Lisp is not...

Name: Mr. Irrational 2013-12-04 20:13

Common Lisp is not a functional programming language.

It is a mutli-paradigm programming language.

Imperative programming is featured in e.g. various prog forms, and mutation through setq and various abstractions built ontop of setq e.g. setf.

Structured imperative programming is featured in e.g. various do forms e.g. [/code]dotimes[/code] and of course
do itself.

Unstructured imperative programming is featured in e.g. the go and tagbody forms.

Now, functional programming is featured through the special forms lambda and function, and the many many forms built ontop of them (apply, funcall etc.).

Object oriented programming is supported through CLOS (defclass, defgeneric, defmethod). CLOS is also the most advanced object oriented system I know if in a serious language*

Metaprogramming is, of course, what makes Common Lisp (and its predecessors) famous. Metaprogramming is accomplished through
defmacro. Unfortunately, ANSI Common Lisp has less features for Metaprogramming than CLTL1 or CLTL2. Luckily, most implementations also implement the latter two standards.

Logic programming is easily accomplished, although ANSI provides no standard interface. A simple implementation of Prolog can be found in Norvig's PAIP book (recommended reading after SICP :)

Common Lisp is also useful for symbolic programming (for example writing symbolic differentiation or integration programs). It is also trivial to implement auto-differentiation in Common Lisp, which is very useful (for example, this was useful in my previous job which involved image processing).

Numerical programming is also very well supported. Specifically the arrays dictionary is very powerful. You are able to create multiple "views" into the same array of different size and rank.

Common Lisp is strongly typed. Types can be declared using a simple syntax, and advanced implementations of Common Lisp have type inference. There are libraries for typed collections, e.g. LIL.

Common Lisp runs in a live image that you interact with. The development environments for Common Lisp are very advanced, because various Lisps were some of the pioneers in this field (e.g. InterLisp and the work of Warren Teitelman).

Last but not least, some Common Lisp implementations (e.g. SBCL and CCL) are systems programming languages. You can write inline assembler, and manual memory allocation with all the pointer arithmetic you want. This means that even a Common Lisp running on a UNIX and not a Lisp Machine can be used to write device drivers and kernel modules.

Common Lisp is the most widely used language of an old tradition of Lisps. Lisp 1.5 -> MACLISP -> ZETALISP -> Common Lisp. Common Lisp also has some InterLisp thrown in, which is from the same tradition, and a teensy bit of Scheme. Common Lisp was not an amalgamation of dialects. It was an evolution of the original Lisp.

There are other evolutions of this tradition, beyond Common Lisp. None are as popular as Common Lisp (for better or worse).

The tradition can be described as any language with the following features:
+ Lexical non-local exits.
+ Unwind protection.
+ A condition system with restarts.
+ Lexical binding.
+ Dynamic binding (thread local)
+ First class functions with optional, keyword and rest parameters.
+ A meta object protocol
+ Powerful, low level macros (and all this implies e.g. first class symbols).
+ Multiple return values.

Some languages in this tradition are EULisp, ISLisp, Dylan, Goo and PLOT (afaict).

A note on Scheme: I think Scheme is a Lisp, however it is not in the tradition of the original Lisps (it's not general purpose, nor multi paradigm, it is its own branch). However, the larger Scheme implementations (e.g. Racket) are closer to the Lisp tradition.

The Lisp tradition has nothing to do with languages such as Haskell, ML, Miranda or other "Functional" programming languages. These other languages are very restrictive, and are at odds with the Lisp tradition in almost every way. Lisp is not a functional programming language for one, it is an imperative, structured, unstructured, functional, object oriented, meta programming systems language. It doesn't care about being pure.

No language with mandatory static typing can ever be a Lisp. There is a huge difference between run-time and compile time typing, just as there is with run-time and compiletime code generation. I think these two quotes sum it up the best

From the Common Lisp mailing list in 1981, Richard Stallman said
"But =member= is supposed to work on any type which does or ever will
exist. It should not be necessary to alter the definition of =member=
and 69 other functions, or even recompile them, every time a new type
is added...

The extensible way of thinking says that we want to make it as easy as
possible to get to as many different useful variations as possible. It
is not one program that we want, but options on many programs."

Ray Dillinger said (in an LtU thread)
"I flatly refuse to limit the inputs to analysis to just the text of
the program. I will use whatever information I have available about
the current state of the program as well, including information that
does not become available before runtime, such as inputs...

That view of type theory (static typing) does not encompass the case
in which the source code may change during a program's run, nor the
case where the definition of a type may change during a program's run."

In conclusion, please stop treating Common Lisp as a functional programming language. I find calling it one is a put off to many good programmers that do not want to use a restrictive and annoying language such as Haskell. Common Lisp is more than that.

Name: Mr. Irrational 2013-12-04 20:31

For example, this is a valid Common Lisp program (an implementation of some algorithm from Knuth, copy pasted from the book Practical Common Lisp (which is a great newbie book))


(defun algorithm-s (n max) ; max is N in Knuth's algorithm
  (let (seen               ; t in Knuth's algorithm
        selected           ; m in Knuth's algorithm
        u                  ; U in Knuth's algorithm
        (records ()))      ; the list where we save the records selected
    (tagbody
     s1
       (setf seen 0)
       (setf selected 0)
     s2
       (setf u (random 1.0))
     s3
       (when (>= (* (- max seen) u) (- n selected)) (go s5))
     s4
       (push seen records)
       (incf selected)
       (incf seen)
       (if (< selected n)
           (go s2)
           (return-from algorithm-s (nreverse records)))
     s5
       (incf seen)
       (go s2))))


A C programmer might cringe at the use of nreverse. No fear, here's a simple utility function with efficient use of pointers.


(defun firstn (n list)
  (if (or (zerop n) (null list))
      nil
      (do* ((i 1 (1+ i))
            (head (cons (car list) nil))
            (tail head (cdr tail))
            (ith (cdr list) (cdr ith)))
           ((or (= i n) (atom ith)
            (if (= i n)
                head
                (progn (rplacd tail ith) head)))
        (rplacd tail (cons (car ith) nil)))))


See. Nothing functional about this language (unless you want it to be, which you should, sometimes).

Name: Anonymous 2013-12-04 22:08

>>1
It is a mutli-paradigm programming language.
NOW you understanded that? You are too late goy

Name: Anonymous 2013-12-04 23:20

>>3
Who are you quoting?

Name: Anonymous 2013-12-05 10:30

>>4
He is quoting >>1-san, as you can see.

Name: Anonymous 2013-12-05 13:04

>>5
Who are you quoting?

Name: Anonymous 2013-12-05 13:09

>>5
He
I am a girl

Name: Anonymous 2013-12-05 13:24

>>5
>le pedophile sage

>>7
>le pedophile sage

Name: Anonymous 2013-12-05 13:36

>>8

Name: Anonymous 2013-12-06 0:00

>>9
>le pedophile sage

Name: Anonymous 2013-12-06 0:20

Name: Anonymous 2013-12-06 0:24

Name: Anonymous 2013-12-06 0:25

Name: Anonymous 2013-12-06 0:25

Name: Anonymous 2013-12-06 2:44

>>11
>le pedophile sage

>>12
>le pdophile sagwe

>>13
le pedophle sage

>14
>le pedophile sag

Name: Anonymous 2013-12-06 13:16

Name: Anonymous 2013-12-06 14:41

>>16
>le pedophile sage

Name: Anonymous 2013-12-06 16:27

Name: Anonymous 2013-12-07 7:52

>>18
>le pedophile sage

Name: Anonymous 2013-12-07 7:52

>>18
>le pedophile sage

Name: Anonymous 2013-12-07 8:39

>>1
Common lisp has one big wart - no static typing. It is irremediable and one should not do any serious work in Common Lisp as the language is simply too restrictive to allow for proper linguistic expression of types, which is necessary for error checking, polymorphism, performance, extensionability of code and documentation.

Name: Anonymous 2013-12-07 8:46

The best Lisp nowadays is Racket because it's got excellent CONTRACTS which are WAY BETTER than any static typing.
It's also got CLEANED UP MACROS which are a lot LESS ERROR PRONE.
And a zillion other things which you can see for yourself.

Name: Anonymous 2013-12-07 11:27


You have been visited by le lambda of doom, repost this in 10 threads or loose your SICP!

  λ
   λ
    λ
     λ
      λ
     λ λ
    λ   λ
   λ     λ
  λ       λ
 λ         λ
λ           λ

Name: Mr. Irrational 2013-12-07 17:46

>> 21

That is not true.

Common Lisp has optional static typing. Furthermore, Common Lisp implementations often perform type inference.

http://clhs.lisp.se/Body/d_type.htm

Also, static typing is not the least bit necessary for error checking, polymorphism, and ESPECIALLY extensibility. In fact, it greatly hinders the last two.

Static typing is good for documentation and compiler hints, however.

Name: Anonymous 2013-12-08 5:32

>>24
If CL cannot check all types statically, then it doesn't have static typing.
And static typing catches all stupid mistakes like mixed up function arguments or missed characters, which is about 95% of all errors.
And polymorphism and extensibility are ONLY possible in a statically typed language as they require constraints to be expressible by the language. Ain't there no way to write something like "f :: (Context a b) => b -> a b -> a b" in Lisp, because it's so restrictive. And without that, you cannot extend your code to work for new types in an efficient and error-checked way.

Name: Anonymous 2013-12-08 5:37

I love it how lispers keep on blabbering about polymorphism and extensibility, when their language is filled with superfluous bullshit like "char>=" and "string>=". If Lisp is so extensible, why couldn't you extend ">=" to work for chars and strings too? Ah, it's because you need static types to achieve that kind of flexibility. Fucking annoying limiting piece of shit that can't even figure out the types of all terms without me having to write tests for fucking everything.

Name: Mr. Irrational 2013-12-08 7:27

>>25

Common Lisp can check all types (in your functions at least) statically. Just declare the type of all your variables.

Also you are once again incorrect in terms of polymorphism and extensibility.

e.g.


CL-USER> (defclass dog () ())
#<STANDARD-CLASS DOG>

CL-USER> (defclass cat () ())
#<STANDARD-CLASS CAT>

CL-USER> (defgeneric speak (animal))
#<STANDARD-GENERIC-FUNCTION SPEAK #x18B9E3E6>

CL-USER> (defmethod speak ((animal cat))
           (format t "Meow.~%"))
#<STANDARD-METHOD SPEAK (CAT)>

CL-USER> (defmethod speak ((animal dog))
           (format t "Woof.~%"))
#<STANDARD-METHOD SPEAK (DOG)>

CL-USER> (defparameter *animals* nil)
*ANIMALS*

CL-USER> (push (make-instance 'dog) *animals*)
(#<DOG #x18B87C8E>)

CL-USER> (push (make-instance 'cat) *animals*)
(#<CAT #x18B86486> #<DOG #x18B87C8E>)

CL-USER> (mapc #'speak *animals*)
Meow.
Woof.
(#<CAT #x18B86486> #<DOG #x18B87C8E>)


Now, I can (without recompiling anything) add new functions over existing data types.

CL-USER> (defgeneric encounter (predator prey))
#<STANDARD-GENERIC-FUNCTION ENCOUNTER #x18BA144E>

CL-USER> (defmethod encounter ((predator dog) (prey cat))
           (format t "Dog eats cat.~%"))
#<STANDARD-METHOD ENCOUNTER (DOG CAT)>

CL-USER> (defmethod encounter ((predator dog) (prey dog))
           (format t "Dog eats dog.~%"))
#<STANDARD-METHOD ENCOUNTER (DOG DOG)>

CL-USER> (defmethod encounter ((predator cat) (prey dog))
           (format t "Cat cannot eat dog.~%"))
#<STANDARD-METHOD ENCOUNTER (CAT DOG)>

CL-USER> (defmethod encounter ((predator cat) (prey cat))
           (format t "Cat cannot eat cat.~%"))
#<STANDARD-METHOD ENCOUNTER (CAT CAT)>

CL-USER> (mapc #'encounter *animals* *animals*)
Cat cannot eat cat.
Dog eats dog.
(#<CAT #x18B104C6> #<DOG #x18B10726>)

CL-USER> (mapc #'encounter *animals* (reverse *animals*))
Cat cannot eat dog.
Dog eats cat.
(#<CAT #x18B104C6> #<DOG #x18B10726>)

This also shows off multiple dispatch.

I can also add new type cases for existing functions (again without recompiling anything).


CL-USER> (defclass rabbit () ())
#<STANDARD-CLASS RABBIT>

CL-USER> (defmethod speak ((animal rabbit))
           (format t "I am not a rabbit, I am a horse!~%"))
#<STANDARD-METHOD SPEAK (RABBIT)>

CL-USER> (push (make-instance 'rabbit) *animals*)
(#<RABBIT #x18B943DE> #<CAT #x18B104C6> #<DOG #x18B10726>)

CL-USER> (mapc #'speak *animals*)
I am not a rabbit, I am a horse!
Meow.
Woof.
(#<RABBIT #x18B943DE> #<CAT #x18B104C6> #<DOG #x18B10726>)


So, as you can see, Common Lisp is not at all restrictive. I am not sure why you think otherwise.

Also, notice how I never defined the type of my *animals* list, and this allowed me to fill it with heterogenous objects. This is usually not so easy to do in (only) statically typed languages.

By definition, static typing restricts your program to only accept types which can be known a-priori. In many cases, this is premature optimization. Dynamic typing imposes no such restriction.

Now, if you want to impose these sorts of restrictions you can. (Even on collections (see the https://github.com/fare/lisp-interface-library)). However, they are restrictions. They do not increase extensibility, and they do not make your program more polymorphic, rather the opposite. Your program will now require recompilation to either add a function over an existing data type (e.g. adding a method to a class definition in Java or C++) or it will require recompilation to add a datatype to a function (e.g. pattern matching in Haskell or ML). So your program will be LESS extensible. Your program will be less polymorphic, because it will only be polymorphic on those types that can be ascertained statically, at COMPILE TIME (from ONLY the program text, not from e.g. USER OR OTHER INPUT AT RUN TIME).

>>26

You are very confused.

If you wish to, you may define a generic >= function quite easily (defgeneric >= (a b))

Name: Anonymous 2013-12-08 7:45

On the subject of types, I once again repeat that Common Lisp is very strongly typed,a nd that it's type system is VERY powerful e.g.

CL-USER> (defun equidimensional (array)
           (or (< (array-rank array) 2)
               (apply #'= (array-dimensions array))))
EQUIDIMENSIONAL

CL-USER> (deftype square-matrix (&optional type size)
           `(and (array ,type (,size ,size))
                 (satisfies equidimensional)))
SQUARE-MATRIX

CL-USER> (defparameter *square-matrix*
           (make-array '(3 3)
                       :element-type 'float
                       :initial-contents '((1.0 0.0 1.0)
                                           (0.0 1.0 0.0)
                                           (1.0 0.0 0.0))))
*SQUARE-MATRIX*

CL-USER> (typep *square-matrix* '(square-matrix float 3))
T

CL-USER> (typep *square-matrix* '(square-matrix float 2))
NIL

CL-USER> (typep *square-matrix* '(square-matrix (unsigned-byte 2) 3))
NIL

CL-USER> (defparameter *not-square-matrix*
           (make-array '(2 3)
                       :element-type 'float
                       :initial-contents '((1.0 0.0 1.0)
                                           (0.0 1.0 0.0))))
*NOT-SQUARE-MATRIX*

CL-USER> (typep *not-square-matrix* '(square-matrix))
NIL

Name: Mr. Irrational 2013-12-08 8:00

>>26


CL-USER> (shadow '<= 'cl-user)
T

CL-USER> (defgeneric <= (a b))
#<STANDARD-GENERIC-FUNCTION <= #x18B8E2BE>

CL-USER> (defmethod <= (a b)
           (cl:<= a b ))
#<STANDARD-METHOD <= (T T)>

CL-USER> (defmethod <= ((a string) (b string))
           (string<= a b))
#<STANDARD-METHOD <= (STRING STRING)>

CL-USER> (defmethod <= ((a character) (b character))
           (char<= a b))
#<STANDARD-METHOD <= (CHARACTER CHARACTER)>

CL-USER> (<= "foo" "bar")
NIL

CL-USER> (<= "bar" "foo")
0

CL-USER> (<= 4/3 2)
T

CL-USER> (<= #\a #\b)
T

CL-USER> (<= #\c #\b)
NIL

Name: Anonymous 2013-12-08 8:16

>>28
You do realize that the words "strongly typed" carry no meaning, right?

Name: Anonymous 2013-12-08 10:09

Common Lisp does not have a static type system and here's proof:
[c]
(defun foo (x)
  (if (> x 0)
    7
    "A string"))

(defun bar (x)
  (+ 1 (foo x)))[/c]
Function "foo" returns a string or a fixnum on a whim, while function "bar" expects "foo" to return always a fixnum. That's a type error, but the code compiles successfully. No static type system!
Now, suppose these two functions are in two remote modules of a large project. The programmer who is looking at function "bar" has no clue that the function "foo" may sometimes return a string, causing a type error. In order to find that out, he would have to look at the implementation of "foo", which is impractical as he cannot traverse the whole codebase and check that there are no square pegs shoved into round wholes anywhere. So the programmer must write a test. But writing tests is a time-consuming operation if you have to check every trivial type error in every control branch, every ramification of every "if", "when", "cond" etc. in your codebase. What if the programmer's test erroneously always calls "foo" with a positive argument? Then the type error will not be detected by that test and will happen only at runtime. Whereas with a good static type system the compiler would be able to traverse the whole code automatically and infer a type error from the definitions no matter how large the project is, how far away the definitions are, and how deeply nested the calls of those functions are. That's one of the benefits of a static type system: the totality of typechecking coverage allows the compiler to detect errors globally while requiring the programmer to make declarations only locally. That's also why "optional typing" is completely impractical: as soon as your typed code starts interfacing with untyped code, the totality of checks evaporates and the reliability of the code drops.

Name: Anonymous 2013-12-08 11:19

Detecting type errors at runtime is like realizing you are eating shit only when you've alredy swallowed half a turd.

Name: Anonymous 2013-12-08 13:47

(recommended reading after SICP :)

CLOSE YOUR FUCKING PARENTHESES MORON WHY ARE YOU DOING THIS??? DON'T USE FUCKING EMOTICONS AND IF YOU DO THEN THE CLOSING PARENS IS THE MOUTH AND YOU'RE PARENTHESES ARE NOT PROPERLY CLOSED!!!!!!! YOU MUST CLOSE THE FUCKING PARENS IS IT FUCKING HARD TO UNDERSTAND?

FUCK YOU DIE IN A FUCKING FIRE AND KILL YOURSELF`

Name: Anonymous 2013-12-08 17:01

>>31

Your proof is not very good. For one, I don't see any type declarations in your Lisp program. Neither for parameters, nor for return types (although a good compiler will infer types from literals).

Try declaring types and then compiling in an implementation with type inference.

If you do not like your compiler's type inference, do your own type checking. You may redefined compile and eval[code]. The languages Qi and Shen do their own static type analysis using a prolog, which I think is a good approach.

Also, it is obviously *NOT* erroneous to call the function with only a positive argument. That is useful and correct functionality. In type terms, if you do [code](defun bar (x) (declare (type (integer 0 *)) ... )
then there should not be a compile time type error.

Furthermore, you should not be calling functions if you do not know what types they return for what inputs, both in statically or dynamically typed languages. If you are using Emacs, then M-. should instantly transport you to a functions definition. You can also use the SLIME inspector, or

Also you don't seem to understand tests. Tests aren't meant to be exhaustive. Tests fulfill a dual role of proving useful properties of your program and as documentation.

You are correct (but not necessarily so, just practically) that mandatory static typing does give the compiler more type information than optional.

Name: Anonymous 2013-12-08 17:19

CMUCL:

(defun f (x)
  (declare (type (single-float -0.5 0.5) x))
  (/ (sqrt (- 1 (* x x)))))

(describe #'f)

f is a function.
Arguments:
  (x)
Its defined argument types are:
  ((SINGLE-FLOAT -0.5 0.5))
Its result type is:
  (SINGLE-FLOAT 1.0 1.1547005)

Name: Anonymous 2013-12-08 21:18

>>31
`>what is a tagged union?

Name: Anonymous 2013-12-08 21:40

>>31

Common Lisp is not "optionally typed". It's typed all the time.

Name: Anonymous 2013-12-09 12:19

>>36
You are wrong, "foo" does not return a tagged union. And the snippet compiles with SBCL (one of the most popular implementations of Common Lisp) even with explicit type declarations:
(defun foo (x)
  (declare (type fixnum x))
  (if (> x 0)
    7
    "A string"))

(defun bar (x)
  (declare (type fixnum x))
  (+ 1 (foo x)))


>compilation finished in 0:00:00.028

and the compiler erroneously overlooks a possible type error:

(describe 'bar)
MYPACKAGE::BAR
  [symbol]
BAR names a compiled function:
  Lambda-list: (X)
  Derived type: (FUNCTION (FIXNUM) (VALUES (INTEGER 8 8) &OPTIONAL))

>>37
It is possible to omit type declarations which makes it an untyped language. Which means that good, fully statically typed code may have to interact with unreliable untyped code from libraries.

>>34
Having to improve a language's type system means that the language is inadequate for professional work.

>it is obviously *NOT* erroneous to call the function with only a positive argument
And yet you or another programmer might call it with a nonpositive argument somewhere else, which will lead to an unexpected type error whose source will be hard to find without a static type checker with total code coverage.

If you are using Emacs, then M-. should instantly transport you to a functions definition

Having to check all the definitions in a large project is a heavy and unnecessary burden that better be automated so programmers have more time to find nontrivial logic errors instead of checking for trivial type errors.

Tests aren't meant to be exhaustive. Tests fulfill a dual role of proving useful properties of your program

Inexhaustive tests do not prove anything because they leave room for unpredictable behavior. If mathematics was based on tests instead of rigorous proofs, we would still be busy writing out consecutive prime numbers in an effort to prove that there is only a finite set of them. Whereas a short but rigorous proof is sufficient to know there is an infinity of prime numbers - without having to explicitly produce even 10 of them. The more things can be proven rigorously about something, the more reliable it becomes and the less tests are necessary to ensure its safety. Compulsory static typing is like that - it allows and forces the programmer to rigorously prove more truths about his program so that a great many tests become unnecessary and one gets more firm guarantees about the runtime behavior of the program.

Name: Anonymous 2013-12-09 13:07

"foo" does not return a tagged union
I never claimed that~

Name: Anonymous 2013-12-09 13:20

Static typing is VERY helpful for iterative development. Whenever you start playing with a piece of code, the compiler readily shows what other pieces must be changed to make the code into what you currently want it to be. Whereas in a dynamic language your code is a hostile unknown mass: when you change a piece, you can only guess what other pieces still work and which will bite you when you try to run them.

Name: Anonymous 2013-12-09 18:57

>>38
It's obviously not an UNTYPED language as values have types. That means its typed. Moreover, the type system is very expressive; a predicate written in Common Lisp can also serve as a type. e.g. you can have a type for sorted lists.

However, it's not a STATICALLY typed language, except for the parts you choose to annotate (statically) with type information.

You can accurately say "static type information is not mandatory" but you cannot say "it is untyped" because that is just false.

Now, it is obviously not the case that inexhaustive tests "don't prove anything". They are programs that prove what you write them to prove. You could for example write a test which walks your function definition and checks for type errors ;)

(really, this could be a useful exercise for you, because you seem to be very confused about what typing is. You think it is magical, it is not. A starting point might be function-lambda-expression. For "extra credit" make your type checker prompt the programmer for fixes, and then apply those fixes.)

I'm not sure what you were trying to explain with your prime number example. However, I do know that programs can deduce proofs according to some rules, and I also know that programs have proved things about prime numbers in the past. I am not sure why you think that the only way to write a program to prove properties about prime numbers involves listing them.

For example, here is a computer program which proves your example; that there are infinitely many primes:

http://www.cs.utexas.edu/users/moore/acl2/v3-3/distrib/acl2-sources/books/quadratic-reciprocity/euclid.lisp

Note that the above proof was written in Common Lisp (using ACL2). The proof itself can be a type in Common Lisp (using satisfies). A conforming ANSI Common Lisp implementation may then be able to do type checking (and or inferencing) using this information, if you choose to supply your programs with it statically. However conforming implementations are not required to do so.

You do make the correct claim that compulsory static typing *forces* the programmer to prove some properties of his program. Namely properties about types. These can be very useful properties, but in many cases they are not. Furthermore, introducing static constraints to your program necessarily limits what it may do at run time, and this is not always desirable, so it should not be forced on to programmers.

Now, in your example the function bar might lead to a type error if called with the wrong inputs. However it also might not. So, just because a programmer might combine foo with another function in a way that the other function is not defined for *some* inputs does not mean that that other function should not exist, or should not be allowed to use the functionality that foo provides.

(If you ever program in Smalltalk (another great language) or various languages in the core Smalltalk family (self, strongtalk, newspeak etc.), you will learn to think about programs as services to other programs. Judging by your confused posts, I think this might be a good exercise for you as well).

This is why you will sometimes hear the claim that (compulsory) static typing is premature optimization. Static typing limits how procedures in your program can be combined, before you even know about all the useful ways they could be combined.

The problems with restricting your program with static type declarations everywhere are even larger when the program can change during it's run.

Also, I noticed you were using SBCL. Please read SBCL's manual (and documentation on its confusingly named "Python" compiler) if you wish to know how to make the most out of static type annotations. Manuals often explain to users of a system how the system and related tools work. ANSI Common Lisp only provides some guidelines and suggestions on how a particular implementation might work, and what it means to be conforming. However conforming implementations may be very different, especially with regard to environment sorts of things (debugging, compiling, introspection etc.).

>>40

I think this more applies when you work in teams, and you are not very familiar with the latest changes your team member has made to his program. I think having executable guarantees is important in a team. Some of these guarantees can be made by executing your compiler with type annotated program text as input, but not many; many guarantees cannot be made a priori.

By the way, even when working in a language with compulsory static typing, you should be writing tests (especially if it is a collaborative project).

Name: Anonymous 2013-12-09 20:54

>>38

Have you checked if SBCL is deriving the type of foo properly (with describe)? If not have you explicitly provided return type information (with the)?

Have you tried explicitly declaring the type of the function (instead of relying on your compiler's type inference) with e.g. (declaim (ftype (function (fixnum) (values (or ...))))

If SBCL already has the right static type for foo then maybe you have not appropriately advised the compiler to spit out warnings on type errors?

http://clhs.lisp.se/Body/d_optimi.htm

What does the manual say? (in SBCL you might want to look at e.g. describe-compiler-policy)

Type checking and inference is a responsibility of your implementation. Please read its manual.

I don't think you have read the manual, and this is probably why you are having so much trouble.

If you have, I apologize.

Also as a wise man once said (paraphrasing)
"Understand Agree Accept: The order in which you perform these tasks when confronted with new information says much about your character"

Name: Anonymous 2013-12-11 5:43

>>40
You're a moron if you write code but can't track the type of data of the variables you use.

Name: Anonymous 2013-12-11 7:28

>>43
>le pedophile sage

Name: Anonymous 2013-12-11 8:34

>>41

I wish to correct myself.

I said "It is not a STATICALLY typed language, except for the parts you choose to annotate (statically) with type information"

This is obviously incorrect. Common Lisp is *always* statically typed. The parts you choose not to annotate with type information are of type T of which all objects in Lisp are subtypes.

Also, this means everytime I compared contrasted Lisp with a "mandatory statically typed" language I did so in error. There is no such contrast. The contrast is with languages which do not have a universal type, some notion of subtyping, and (I suppose) don't assume that universal type unless otherwise specified.

Everything else is correct.

That is all.

Name: Anonymous 2013-12-14 14:10

Actually, you can create types at runtime even in a statically-typed language - just use existential types. So Lisp once again is not an original or superior language, just as it is with macros, closures, OOP, tail-call optimizations and every other feature of Lisp.
Common Lisp is, however, a good toy and educational language, especially suited for creating other toy languages.

Name: Anonymous 2013-12-14 18:53

Once again, Anonymous is flaunting his type system sophistry all over the place.

An existential type is not what you think it means, and no, existential types alone don't allow types to be created at run time, they just let you use types created at run time in already existing functions. Something else is required to create them.

Also, I agree Common Lisp is a great toy language, and it is a great educational language, as well as a great language for making other toy languages. This is because it is just great all around, so it is no wonder it would also excel at these things as well.

However I disagree that it is not original or superior.

The Common Lisp line has been very "original" in that it is the origin of many concepts and techniques. The extended Lisp line even more so.

To my knowledge it is also the most superior language. I do not know of any other language which rivals the versatility of Common Lisp, or which makes it easy for a skilled programmer to write performant, understandable, and large systems.

Of course Common Lisp has flaws. For one, it will make a bad programmer (while he remains bad, but they are known to improve) really bad, so it is not very good for use in many teams, in current development strategies, because many teams have at least one newbie.

Also Common Lisp has other flaws. However these flaws are difficult to understand, and require intense study of the standard and other Lisps. Furthermore there have been new ideas and techniques in the Lisp world, which when proven in the field, may make it into a future evolution of Common Lisp (e.g. those lexically scoped namespace thingoes).

One thing about the Common Lisp community is that it is very conservative. Common Lisp programmers have usually been writing programs for >30 years, and have written complicated systems in >15 languages. Common Lisp programmers usually know the origins, the reasons, and the short term and long term effects of various ideas in computer science. This is why a Common Lisp programmer looking at Rich Hickey (a newbie Common Lisp programmer) designing a language look at it not unlike the parent of a child with downsyndrome look at that child as he learns to read; with love and adoration. It is also why Common Lisp programmers look at something like Haskell and expecially it's community with utter disgust.

Finally while we're on the subject of toy languages (as a derogative), one way to know if your language is serious is to think: "Have real machines, and real operating systems, been written for and in this language? Have these been sold for hundreds of thousands of dollars a piece? Did they have a whole suite of applications for documentation preparation, 3D CAD, 3D animation and modelling, film production, image manipulation, computer algebra, robot control etc. that people actually paid for written in that language?" If the answer to any of these questions is no, it is your language which is a toy (derogative) language.

Name: Anonymous 2013-12-14 19:35

In nomine Symbolics, Genera et Sussman sancti

http://lispm.dyndns.org/symbolics-ui-examples/symbolics-ui-examples.html

Name: Anonymous 2013-12-14 19:47

>>47-48
old! dead!

Name: Anonymous 2013-12-14 19:52

>>49

I'm typing this from Genera right now :)

Name: Anonymous 2013-12-14 20:01

>>50
screenshot

Name: Anonymous 2013-12-14 20:44


Don't change these.
Name: Email:
Entire Thread Thread List