14 ms·
Ask HN: Learning Lisp, and I have some questions
So this weekend I am learning some LISP. I thought best way would be to get some basic introduction (which I already did), and then build a project. So for practice project I have decided to make a URL shortner web service. I am setting up SBCL as that seems to be the most popular. I have few questions though:
- What are my package manager options? I can see quicklisp and qi. The quicklisp seems to install everything in a global folder. I am looking something closer to npm or bundler that stays local to my project. Qi seems like it. But I am still confused, what are my options here?
- What web frameworks are recommended. I don't need a full fledged framework, I need something micro, that just get's the job done. What are my options here and what's most recommended?
- For storage database I want to use something embedded and fast. SQLite is one option, what are my other options? Are there any "pure lisp" implementations of Key/Value stores?
- For hosting I know I can get it running on a VPS. Are there any other options I am not aware of out there?
I am total n00b so some questions might sound stupid to full time lispers, so bear with me :)
- pedrodelfino 9y agoI am also a beginner. I don’t have much experience with web development (I am an undergraduate Applied Math student with a deep interest on computer science). If you don’t mind, I would you suggest you to change your approach to learning Lisp. Get the classic freely available SICP book (from MIT professors) and do some exercises. The classes are also available at MIT OCW. Another good book is “How to Design Computer Programs”, from the guys who created Racket, a Lisp dialect. Maybe, these books will give you a purer sense of the language. Web frameworks are a different thing. In conclusion, if you are trying to understand Lisp, have a go on pure Lisp. Btw, Racket is great, I prefer Racket an Dr. Racket than Common Lisp.
- CarolineW 9y agoI don't entirely agree with your reply, but I think it's unreasonable that it's being downvoted. I've upvoted it to try to balance that, although it's not clear my vote will count for much, if anything. I think what you've said is reasonable, although it doesn't really address the poster's questions.
- arh68 9y agoI think all of that is covered in Loving Common Lisp, by Mark Watson [0]. It's probably what you're looking for. Enjoy [0] https://leanpub.com/lovinglisp https://leanpub.com/lovinglisp
- rjsw 9y agoI would just store any data in the Lisp system itself, you have hashtables built in. Why do you need to host it somewhere else ? Just get it running on your development machine.
- crimsonalucard 9y agoWeb applications are typically stateless, with state being managed by an external service such as a database.
- pavlov 9y agoIt’s not a great architectural choice for most web apps though. I think the reason we’re stuck with it being the default is simply historical: the CGI script execution model, rise of PHP, etc.
- jjnoakes 9y agoThe upside of an external service (even an embedded library if you want to go small, like sqlite) is that it handles the hairy persistence problem for you. If you keep your data in memory, you may eventually want to store it somewhere so you can restart the service, reboot the machine, restore from older state, etc. If you start managing the disk writing yourself and care about the edge cases (like ungraceful termination of your process or the os) you have quite a bit of work ahead of you. A service or library takes care of all of the right fsync calls on the right entities in the right orders for you.
- pavlov 9y agoDatabases are fine. I don’t like the rigid idea of a stateless web application server that needs to hit the database for everything. In my view, the web application server’s primary function is to be a smart cache that responds to HTTP requests. The developer’s goal should be to prevent most requests from having to wait on a socket to return data.
- gkya 9y ago- If I'm not mistaken Quicklisp does allow different versions of a package coexist. - Hutchentoot is very popular. Haven't used though. - If you want common lisp only, IDK, but Clojure has Datomic. Though wrt databases, I'd rather care about quality, not implementation language, because it's mission critical software. - NearlyFreeSpeech.net has SBCL and GNU Guile. But it's shared hosting. It should be easy to put an interpreter binary on a VPS kind-of service though. For Heroku there's a pack on github, though I don't have the link. The only Lisp project that I could further is my emacs.d, because that's what I really use. I think that's key to learning something, having a real use for it. I wish you luck in your lisp adventure!
- aidenn0 9y agoQL doesn't allow different versions of a system to coexist, but you can have multiple QL installs on a system for the rare cases in which you need two different versions of a system for two different projects. Qlot does allow more finer grained control, but I've never had a need for it.
- s_kilk 9y agoIf I may ask a related question, how do lispers deal with the absence of a real boolean type in CL? My mind absolutely boggles at the prospect of not being able to tell the difference between null, false, and the empty list. Am I missing something?
- taeric 9y agoI find in most cases, I just don't care about the difference. That said, pretty sure you can find the specific answer if you need it.
- juki 9y agoMost of the time there just isn't any need to make a difference between the three. There are basically just two common situations where you need to be able to tell the difference: 1. Telling apart optional arguments to a function that weren't given from arguments that were given and were NIL. Typically giving a default value for the argument is sufficient to avoid the problem, but you can also add an extra parameter that tells whether the argument was given. (defun foo (&optional (x :default-value xp)) ;; X holds the argument given by the caller, or the keyword ;; :DEFAULT-VALUE if nothing was given. ;; XP is T if the argument was given, or NIL if it was not given. ) 2. Finding an item that may be NIL. Functions such as GETHASH (which looks up a key in a hash table) usually allow you to specify a default value, and they will return a second value to indicate whether something was found. ;; Increment the value of KEY in TABLE, or if the key doesn't ;; exist, use 10 as a default, increment that and set the ;; result to the table. (incf (gethash key table 10)) (multiple-value-bind (value existsp) (gethash key table) ;; VALUE holds the value if it exists, or NIL if it doesn't. ;; EXISTSP is T if the key exists, or NIL if it doesn't. ) Notice that in CL additional return values can be ignored if you're not interested in them, so you only need to use MULTIPLE-VALUE-BIND when you actually need it. You could also wrap it in a trivial macro if you're using it a lot. (defmacro if-some-let ((var form) &body (then &optional else)) (let ((somep (gensym "SOMEP"))) `(multiple-value-bind (,var ,somep) ,form (if ,somep ,then ,else)))) (if-some-let (val (gethash key table)) (format t "Found: ~a~%" val) (format t "Didn't find.~%"))
- eatonphil 9y agoPractical Common Lisp [0] is a really great (free) book that will help you understand the language better quickly. I read through that with three other guys at Linode in an informal book club and it went well. All of Zach Beane's blog posts are great for starting out with quicklisp, but here is a good one [1]. [0] http://www.gigamonkeys.com/book/ http://www.gigamonkeys.com/book/ [1] http://xach.livejournal.com/278047.html http://xach.livejournal.com/278047.html
- jakelaboss 9y agoLisp Programmer here, - quicklisp is the default for package management. If you need to load a different version of a package you can use the local projects dir. I've never used Qi before, so I really can't say anything on it. - For a framework I would recommend either Clack[1] (relatively small but featureful) or Ningle[2] (micro-framework).Both support multiple backends including Huntchentoot. - There are object store databases and serializers like cl-store and cl-prevalence, but if you really want to take full advantage of Lisp I would recommend you use hash tables and reader macros. There's also plenty of mature (by lisp standards anyway) SQL APIs and ORMs like postmodern[3]. - For hosting I use AWS, haven't used anything else so can't say much on it. [1] https://github.com/fukamachi/clack https://github.com/fukamachi/clack [2] https://github.com/fukamachi/ningle https://github.com/fukamachi/ningle [3] https://github.com/marijnh/Postmodern https://github.com/marijnh/Postmodern
- scribu 9y agoIf you’re hoping to use a lispy language professionally, I would suggest looking at Clojure. It’s a much smaller language than Common Lisp and has a very active ecosystem. Leiningen is the standard build tool: install dependencies, run tests etc. http-kit gives you the minimum needed for implementing a web server. There are several key-value stores written in Clojure, but I would stick with SQLite (with the Korma library for nice composable syntax).
- junke 9y ago- the global folder of Quicklisp works for most purposes. It is built on top of ASDF, which you can configure too. But I would not worry about that first. - for a URL shortener, Hunchentoot is already enough. Hunchentoot comes with an "easy-acceptor" scheme, which requires only (defparameter server (make-instance 'easy-acceptor :port 8080)) followed by (start server). But maybe you will need to define you own subclass of "acceptor" instead, I don't know. - For storage, you can use hash-tables and serialize them with cl-conspack. (let ((hash (make-hash-table))) (setf (gethash :name hash) "YourName") (conspack:encode-to-file hash #P"/path/to/hash")) Note that conspack:decode-file returns a list of values. You can also interact with databases.
- baldfat 9y agoI would say that Racket is by far the best Lisp to learn. It has the basically been founded to teach programming and it has been fleshed out into a very strong general purpose language. Watch these videos on a quick overview of Racket https://www.youtube.com/watch?v=vKjOTdVi99A&list=PLNm0vh7FGMys545h4jmaJ1tX8qo8kh9Dt https://www.youtube.com/watch?v=vKjOTdVi99A&list=PLNm0vh7FGM... You could program your pet project right afterwards. Also the documentation in Racket is better than any other community I have ever found. Clear, concise and uniform. If I was to direct anyone into learning Racket I would say that 1) Realm of Racket is a great start for the language 2) How to Design Programs (Free online and a great resource) Racket is just a great ecosystem that makes Deployment a piece of cake. I am a big polyglot but Racket has been my favorite find the past decade. Last time I got excited about a language was Python.
- fasquoika 9y agoJust a disclaimer because the parent didn't say it: Racket is a Lisp, but it is not Common Lisp. It is far more similar to Scheme, and you will have to make some adjustments coming from Common Lisp. That said, it is indeed one of the best Lisps today, especially for learning
- ethagnawl 9y ago> What web frameworks are recommended If you're intent on using Common Lisp, check out: https://github.com/fukamachi/clack https://github.com/fukamachi/clack If you're willing to consider Clojure (widely used, actively developed, target platforms: JVM, browsers, CLR), there are _lots_ of options - I've had success using Ring/Compojure in small, web service projects. Check out Clojure Toolbox's "web frameworks" section: https://www.clojure-toolbox.com https://www.clojure-toolbox.com Otherwise, if you're interested in Scheme (Guile, in this case), Artanis looks promising: http://web-artanis.com/ http://web-artanis.com/
- deleted 9y ago[deleted]
- cat199 9y agofocus on syntax / macros / CL packages - maybe make a 2-layer set of macros/functions to translate urls, deal with terminal IO (you can hook up a TTY to a web server simply), and store the results to a simple assq-on-disk affair, the rest will come later. get this, then asdf and gen executable; you can run multiple lib copies in cl packages and don't need them in production anyway, so global folder isn't important; that said you can customize quicklisp install.. write a macro to do this for you for pratice lol :) the power is in the lisp language & syntax extension, not reproducing 'npm install foo' using native calls and getting frustrated that the ecosystem is smaller excuse snarky tone, simply typing quickly
- cat199 9y agoalso, if you aren't using commercial lisp, use emacs. really. though it's the editor war, lisp-based-emacsen were written simultaneously with the lisp machines by the same people .. lisp+emacs grew together like c+unix; which is also a good analogy since it is really another world, best to throw out all baggage if you can..
- earenndil 9y agoYou can also use ABCL in order to get access to JVM frameworks.
- arnoooooo 9y agoRegarding Quicklisp, when I want to have all the dependencies in the project directory, I run sbcl with the option --eval '(setf asdf:central-registry (list #p"." #p"./lib"))'
- rcdwealth 9y agoFor such simple application all you need is LISP implementation. 1. Package manager is not required. 2. Framework is not required, that is simple application, you can have running as CGI under any server. 3. Storage database? Just use the LISP date stored in files, and you can even keep username/password there.
- jiyinyiyong 9y agoI'm using ClojureScript. I would definitely argue that ClojureScript is the right language you should pick up. It's based on JavaScript ecosystem and all pieces from npm are available. It's the largest ecosystem currently. If you argue JVM is the largest one, then just choose Clojure. For ClojureScript, what package manager? npm. Also you may need Clojars and Maven for some Clojure(Script) packages. But you can use shadow-cljs to abstract the Clojars part. What framework? search in Node.js community, you can use it in ClojureScript. Which database? check out Node.js community. How to run on VPS? it's Node.js question.