Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> (variables don't have types unlike C# and friends, they're just named registers where you can shove anything)

This depends on the implementation one uses: SBCL does type checking:

  * (defvar *a-number* 0)
  *A-NUMBER*
  * (declaim (type (integer 0 100) *a-number*))
  (*A-NUMBER*)
  * (setf *a-number* 10)
  10
  * (setf   *a-number* "ten")
  ; in: SETF *A-NUMBER*
  ;     (SETF *A-NUMBER* "ten")
  ; ==>
  ;   (THE (MOD 101) "ten")
  ; 
  ; caught WARNING:
  ;   Constant "ten" conflicts with its asserted type (MOD 101).
  ;   See also:
  ;     The SBCL Manual, Node "Handling of Types"
  ; 
  ; compilation unit finished
  ;   caught 1 WARNING condition
SBCL does that a compile time, too.

> - the language-adjacent concept and nomenclature like Systems. What Lisp calls Packages are pretty close to what most other languages would call namespaces, and what lisp calls Systems are what other languages call Packages, or maybe libraries.

Lisp is old, these names are from end 70s ("package") and ~1981 ("system") - at that time they were used in the MIT Lisp Machine system software.



>SBCL does type checking

It does, and values have types but variables don't. Without the DECLAIM facility you can do the following:

    (defvar *foo* nil)
    (setf *foo* 123)
    (setf *foo* "dank memes")
Whereas in C# you cannot do the following:

    int i = 123;
    i = "dank memes";
Thats all I meant.


No, the differences is that in Common Lisp / SBCL type declarations are optional (note though: there is also type inference in SBCL), type declaration are more verbose, type declarations are sometimes a separate expression and a variable by default has the type T, unless the compiler can infer another type.

  (declaim (type (integer 0 100) *a-number*))
Above does not declare the type of a value, it declares the type of a variable to be an integer in the range of 0 to 100.

In SBCL we can also query for the type of that variable:

  * (defvar *a-number* 0)
  *A-NUMBER*
  * (declaim (type (integer 0 100) *a-number*))
  (*A-NUMBER*)
  * (SB-CLTL2:VARIABLE-INFORMATION '*a-number*)
  :SPECIAL
  NIL
  ((TYPE MOD 101))
The third returned value is the declared type.

Another example: a function with two local variables. One variable is declared to be of type INTEGER and the other of type STRING. We then try to set one variable to the value of the other:

  * (defun foo (a b)
      (declare (type integer a)
               (type string b))
      (setf a b))

  ; in: DEFUN FOO
  ;     (SETF A B)
  ; ==>
  ;   (THE INTEGER B)
  ; 
  ; caught WARNING:
  ;   Derived type of COMMON-LISP-USER::B is
  ;     (VALUES STRING &OPTIONAL),
  ;   conflicting with its asserted type
  ;     INTEGER.
  ;   See also:
  ;     The SBCL Manual, Node "Handling of Types"
  ;
What you see above is that the SBCL compiler a compile time detects a type error and warns. There are no values involved.

See https://en.wikipedia.org/wiki/Gradual_typing




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: