Hacker News new | ask | show | jobs
by mattjones 6289 days ago
Libraries aren't the issue. I use Chicken Scheme for a few things, which has plenty of libraries and a fantastic package system called eggs. Sure, other languages like Perl and Python have more libraries now, but that's not what made them popular.

What made them popular was the design of the core languages. I started using Ruby because it was faster to type and easier to remember how to do things than Perl, not because it had more libraries, which it didn't.

The problem with Scheme is that the core language isn't terse enough, and so it gives the impression that it will be hard to do things. And that's correct. Scheme requires much more typing and is harder to remember than Ruby.

Consider:

Ruby:

  h = {}
  h[:foo] = "hi"
  h[:foo] #=> "hi"
  h[:bar] #=> nil
Scheme (Chicken):

  (define h (make-hash-table))
  (hash-table-set! h 'foo "hi")
  (hash-table-ref h 'foo) ;; "hi"
  (hash-table-ref/default h 'bar #f) ;; #f
That, in a nutshell, is why people don't use Scheme. The people who made Perl etc. popular hate typing, and the core language of Scheme forces you to type a ton. There are other problems like really slow string functions, things that should be core being in SRFIs, libraries being called "SRFI 18" rather than normal things like "threads" so that it's extra hard to tell where a function is coming from, where its documentation is, or what you have to import to get it. Lack of libraries (if indeed that's a problem for you) is downstream of the core problem, which is that Scheme has a lot of clumsy design features that discourage would-be library writers from using the language a lot.

This isn't a Lisp problem, it's a Scheme one. A Lisp with a better core and enough users would get lots of libraries eventually, just like any language.

I think Scheme is good for teaching though, and would rather learn it in a course than Python.

3 comments

Clojure:

    user> (def h {:foo "hi"})
    #'user/h
    user> (h :foo)
    "hi"
    user> (h :bar)
    nil
The main difference with the Ruby is the immutable by default data structure, which is why I replaced the assignment with a literal definition of the map. In any case, I think this demonstrates how Clojure has stolen some of the good ideas from Ruby and Python in addition to stealing many of the best ideas from other Lisps.
That is a great demonstration that Scheme's problems are not Lisp problems. I'm hoping that we're about to see a lot more experimentation with new Lisp dialects.
> Libraries aren't the issue

You say libraries aren't the issue, but the discussion is about a blog pst that said: "And why Python, then? Well, said Sussman, it probably just had a library already implemented for the robotics interface, that was all."

I'm sure your experience is grounded in a general reality. But the post you disagreed with was about a specific case: i.e. the one described in the blog post.

From the point of view of a person at an instant in time, libraries are a concern. But when we're talking about Scheme being displaced by Python at MIT, where Scheme was developed 30 years ago, we really ought to ask what's been happening to Scheme during that 30 years.

The problem, at MIT and elsewhere, is that hackers don't like hacking Scheme enough. Python has more libraries than Scheme now, but that's not the main thing that made more people use it. People use it because they prefer the language. This is something that Sussman and others at MIT should be trying to understand, but it doesn't strike me that they are trying to understand it. They're just saying "Python has a better robotics library -- oh well!" as if this were something completely random that they have no control over. That doesn't seem like the sort of attitude that produced Scheme in the first place.

My point of contention with the comment I replied to is the idea that fixing the problem is a question of writing more libraries for Scheme. Writing or interfacing to libraries for numerics, 3D graphics, etc. is a trivial task compared to making a language hackers love.

Now, maybe hackers' distaste for Scheme is Scheme's fault, or maybe it's hackers'; but in any case, the issue is with the core language, not the libraries. And based on my personal experience with Scheme I would say that enough of the fault lies on Scheme's side that it's worth fixing.

The prospect of Scheme as a potential mainstream programming language went down with the rest of the Lisp ship in the late-1980s AI winter - the same one that sank Symbolics and anyone who was remotely Lisp-guilty by association.

It is no accident that it survived almost exclusively in non-saltmine sanctuaries like MIT, where industry herdthink held less sway. In the linked article, Sussman directly admits that he is unable or unwilling to fight back against the intellectual decay that has consumed non-academic programming.

He has decided to "go with the flow" - namely, the flow of industrial sewage into students' heads.

Ease of programming isn't the issue, at least not when it comes to writing libraries that must interface with C code (as a robot-interfacing library is likely to). Most Schemes and Lisps can interface to C by means of a few simple declarations, while Python requires the C code to accept and return Python's internal data structures (and convert them to a form that can be used by C code), and requires it to register those functions that are to be made visible to Python.

Scheme (PLT)

  (require scheme/foreign)
  (unsafe!)
  (define my-c-lib (ffi-lib "libmylib")) ;; loads libmylib.so
  (define my-c-func (get-ffi-obj 'my_c_func my-c-lib (_fun _long -> _long)))
  ;; The C code does not need to take Scheme into account--
  ;; Existing C libraries can be interfaced with Scheme
  ;; with a trivial amount of effort.
C (to be linked against Python code-- Python can load the resulting shared library as if it was written in Python). Notice that all this code does is interface Linux's htonl function to Python:

  #include <Python.h>
  #include <netinet/in.h>
    
  static PyObject *
  py_htonl(PyObject *self, PyObject *args) {
     long my_arg;
 
     if(!PyArgParseTuple(args, "l", &my_arg))
         return NULL;
     return PyBuildValue("l", htonl(my_arg));
  }
  
  static PyMethodDef methods[] = {
      {"htonl", py_htonl, METH_VARARGS,
       "Demonstrate Python's C interface\n"}
  };
  
  static char module_doc[] = "Demonstration";  
  
  PyMODINIT_FUNC
  initfunc(void) {
    PyInitModule3("mylib", methods, module_doc);
  }