Hacker News new | past | comments | ask | show | jobs | submit login

One downside of Lisp and Smalltalk for large projects may be that there is no official mechanism for declaring types and interfaces. Even if you can adopt your own conventions for implying the types they are just your convention and other programmers might have difficulty grokking and trusting them.

Hyper-productive languages may be hyper-productive just because they use dynamic typing and static types may be better for creating a large piece of software by many programmers evolving over years hopefully decades.




>that there is no official mechanism for declaring types and interfaces.

This is not true for Common Lisp.

Want to declare types? "(declare (type ...))"

Interfaces? CLOS allows "generic functions", which can achieve the same as interfaces, and are light years beyond the typical OOP system.


I wasn't aware of Common Lisp type declarations, thanks. But they are optional (right?) so in practice if they are not there they do little good.

Could you tell a bit more about how generic functions do the same thing as Interfaces? Can you use them as part of a type-declaration? Say like a Java Interface can be used as a Type in a type-declaration of a method.


> But they are optional (right?) so in practice if they are not there they do little good.

That depends on the compiler. The SBCL compiler will use it as type assertions, adding type inference and will do checks at compile time.


>But they are optional (right?) so in practice if they are not there they do little good.

Modern implementations like SBCL also do type inference as well and do tell you about compile-time type errors.

CL is also a very strongly typed language so type errors are going to be caught by the implementation sooner or later.

Not that I care, though. Type mismatch errors are my least concern.

>Could you tell a bit more about how generic functions do the same thing as Interfaces?

You'll have to read the online chapter about Generic functions of the "Practical Common Lisp" book, available online for free and already a classic. Common Lisp Object System (CLOS) cannot be explained in a few words.

>Can you use them as part of a type-declaration?

Object classes can be used in type declarations.

>Say like a Java Interface can be used as a Type in a type-declaration of a method.

CLOS goes beyond and is even more powerful than what Java offers. See "multimethods" and "polymorphic dispatch".

CLOS OOP makes Java OOP look like looking at a Little Tikes car from an actual Formula 1 car. And I say this as a person who worked as a paid Java developer for "serious" stuff for years.


> (CLOS) cannot be explained in a few words.

No doubt. I was just curious how "generic functions" in particular could help in defining types and interfaces. I was not asking for the whole story about the whole of CLOS.


>I was just curious how "generic functions" in particular could help in defining types and interfaces. I was not asking for the whole story about the whole of CLOS.

I understand.

For something similar like a Java interface, you could define generic functions for each method your interface declares. For example consider interface IStream with methods open(), close(), sendbytes(b) and readbytes(b)

In Lisp you could declare the following generic functions: open(x), close(x), send(a, b), and read(a,b).

Then you simply define methods for any kind of (concrete) stream. Moreover, "send" and "read" could be defined to send/read not just bytes, but also any other kind of object. Or you could also define a "send" and "read" that works from stream to stream. For the latter, on java you would have to either redefine IStream, extend IStream, or create another class specialized on copying from Stream to Stream. On Lisp you just define an additional method for the generic function send(a,b) where a and b are both streams.

The CLOS system will take care of calling the correct method. If there isn't a correct method this would signal an error: "No applicable method".


Ever heard of CLOS, the Common Lisp Object System? It has 'classes', 'generic functions' with 'methods' which support multiple dispatch over classes, etc. It was defined in the late 80s and integrating it into Common Lisp made it the first standardized OO language.

   (defclass person ()
     ((name        :type string)
      (age         :type (integer 0 150))
      (exployed-by :type company)))

   (defmethod rename-person ((p person)
                             (old-name string)
                             (new-name string))
    ...)

   (rename-person some-person "Jim" "James")


I've heard of it but not used. Being able to say: "(name :type string)" looks great.

Does it mean the system gives me an error if a method is called with a number where a string was declared to be the argument type?


At runtime every CLOS implementation will do that. Note that it allows for more than one parameter to be specialized. In the example FOO is using multiple dispatch with two parameters P and S. When we call FOO with arguments for which no method exists we get:

  CL-USER 22 > (defclass person ()
                 ((name        :type string)
                  (age         :type (integer 0 150))
                  (exployed-by :type company)))
  #<STANDARD-CLASS PERSON 4210214F63>

  CL-USER 23 > (defmethod foo ((p person) (s string))
                 (list p s))
  #<STANDARD-METHOD FOO NIL (PERSON STRING) 402025C653>

  CL-USER 24 > (foo (make-instance 'person) 3)

  Error: No applicable methods for #<STANDARD-GENERIC-FUNCTION FOO 4060000B5C> with args (#<PERSON 402025F1DB> 3)
    1 (continue) Call #<STANDARD-GENERIC-FUNCTION FOO 4060000B5C> again
    2 (abort) Return to top loop level 0.

  Type :b for backtrace or :c <option number> to proceed.
  Type :bug-form "<subject>" for a bug report template or :? for other options.

  CL-USER 25 : 1 >


Note to galaxylogic: When lispm wrote:

     (defmethod foo ((p person) (s string))
                     (list p s))
He was implicitly defining a "generic function" "foo" of two arguments.

Defmethod was defining an implementation of the generic function foo for arguments person with string.

One could later put something like:

     (defmethod foo ((p person) (p person))
                     (send-greeting p p))
And thus define a "foo" that works on two persons, etc.

CLOS allows specializing not just on classes, but also on specific instances, so some method applies only for a specific instance. For example a "foo" that applies only to a particular "important" person.




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

Search: