5 ms·
Lisp hasn't failed. Software engineering has failed to reach the conceptual level that Lisp operates at.
by abrax3141 7y ago
Lisp hasn't failed. Software engineering has failed to reach the conceptual level that Lisp operates at.
- ben509 7y agoLISP doesn't really have a hugely complex conceptual level. It gives you a list, which can be combined to form complex structures, and also a list can be code. MLs took ideas in LISP much further and imposed powerful type systems on them, so they appeal to a smaller audience than LISP does. And the multi-paradigm languages simplified ideas from LISP to be usable for a broader audience, and brought in new ideas from elsewhere. So I don't think SE has failed to reach LISP, if anything, it's surpassed it.
- dreamcompiler 7y ago> It gives you a list, which can be combined to form complex structures In Common Lisp, using lists for most data structures is a mark of a poor programmer. If you think Lisp is about list processing, you perhaps need to become familiar with how Lisp has evolved since the 1970s.
- singularity2001 7y agohonest question: is the following the way you do hashmaps in lisp: ? ``` (setq a (make-hash-table)) (setf (gethash 'color a) 'brown) (setf (gethash 'name a) 'fred) (gethash 'color a) => brown (gethash 'name a) => fred (gethash 'pointy a) => nil ``` vs ``` a = { color:'brown', name:'fred' } ```
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- dreamcompiler 7y agoYes, that's the lowest-level API. But if you have a lot of hashmaps to specify literally, you could create a DSL for them as follows: (defparameter a '((color brown) (name fred))) (defun make-hashmap (pairs) (let ((ht (make-hash-table))) (mapc (lambda (pair) (setf (gethash (car pair) ht) (cadr pair))) pairs) ht)) (defun showhash (hash-table) "Show hash-table" (maphash #'(lambda (key value) (format t "~%~S : ~S" key value)) hash-table)) (showhash (make-hashmap a))
- fiddlerwoaroof 7y agoOr you can use reader macros (or normal macros) like fset does: https://fwoar.co/pastebin/d281bd93810a1f9491ec42080ea222af80077490.nil.html https://fwoar.co/pastebin/d281bd93810a1f9491ec42080ea222af80...
- dreamcompiler 7y agoIn principle I agree that reader macros are handy. In practice I mostly avoid them because reader macros don't have separate namespaces in CL, so it's likely your reader macro will step on one from an external library. (Yes, you can carefully bind *readtable* before compiling code, but methods for doing so are ad hoc and not standardized. This is a perfect example of a convention that Common Lisp programmers need to establish formally when using CL for software engineering.)
- fiddlerwoaroof 7y agoThis problem is mostly solved with named-readtables: You declare a readtable like this: https://github.com/fiddlerwoaroof/objc-lisp-bridge/blob/master/readtable.lisp#L24 https://github.com/fiddlerwoaroof/objc-lisp-bridge/blob/mast... And use it like this: https://github.com/fiddlerwoaroof/objc-lisp-bridge/blob/master/objc-data-extractors.lisp#L16 https://github.com/fiddlerwoaroof/objc-lisp-bridge/blob/mast...
- 7y ago
- keymone 7y agoNah, I just do {:color “brown” :name “fred”}
- dreamcompiler 7y agoThat works in Clojure but not "Lisp" in general, which is what the parent asked about and for which they gave an example.
- deleted 7y ago[deleted]
- svetlyak40wt 7y agoYou can define your own syntax in CL: CL-USER> (set-macro-character #\{ (lambda (str char) (declare (ignore char)) (let ((*readtable* (copy-readtable *readtable* nil)) (keep-going t)) (set-macro-character #\} (lambda (stream char) (declare (ignore char) (ignore stream)) (setf keep-going nil))) (let ((pairs (loop for key = (read str nil nil t) while keep-going for value = (read str nil nil t) collect (list key value))) (retn (gensym))) `(let ((,retn (make-hash-table :test #'equal))) ,@(mapcar (lambda (pair) `(setf (gethash ,(car pair) ,retn) ,(cadr pair))) pairs) ,retn))))) T CL-USER> {:foo 100500 :bar 42} #<HASH-TABLE :TEST EQUAL :COUNT 2 {1005879463}> CL-USER> (alexandria:hash-table-alist #v1) ((:BAR . 42) (:FOO . 100500)) CL-USER> And define a printer for the hash to output it as desired: CL-USER> (defmethod print-object ((obj hash-table) stream) (princ "{" stream) (loop with indent = nil for key being the hash-keys in obj using (hash-value value) when indent do (format stream "~% ") unless indent do (setf indent t) do (format stream "~S ~S" key value)) (princ "}" stream)) #<STANDARD-METHOD COMMON-LISP:PRINT-OBJECT (HASH-TABLE T) {10040C9F83}> CL-USER> {:foo 100500 :bar 42} {:FOO 100500 :BAR 42}
- singularity2001 7y ago
- deleted 7y ago[deleted]
- flavio81 7y ago>honest question: is the following the way you do hashmaps in lisp: ? >vs >a = { color:'brown', name:'fred' } For such simple data you don't need to use a hashtable in Lisp. You just do: (:color "brown" :name "fred") then you get the name using: (getf x :name) Btw, anything you can represent in JSON, you can also represent in Lisp s-expressions. But not the other way around(!) Hashtables, in Common Lisp, are intended for big amounts of data, that's why CL includes several options to tune their performance.
- dreamcompiler 7y ago> (:color "brown" :name "fred") This works, but it's a plist and thus O[n] for lookup. I assumed the questioner wanted an O[1] data structure; thus a hash table is the better answer. (Granted it makes little difference when n is small.)
- flavio81 7y ago>This works, but it's a plist and thus O[n] for lookup. I assumed the questioner wanted an O[1] data structure; thus a hash table is the better answer. (Granted it makes little difference when n is small.) There was a test on some Common Lisp implementations, of hashtables versus plists on access speeds. On small (<30?) datasets, plists were much faster than hashtables. Bigger than that, the constant access speed of hashtables makes HTs a more sane choice. The other thing is memory consumption -- on CL, plists are very frugal.
- ben509 7y agoAs far as representing code the same way it represents data, that's still done with lists. And the fact that code and data have an identical representation is the most unique feature of LISP. Recall that the original claim was that software engineering hasn't caught up to LISP. Making metaprogramming trivial by using an identical presentation for code and data is the key insight of LISP, and we do a lot of metaprogramming in many languages, so yes, we've caught up with LISP.
- dreamcompiler 7y agoIt's true that "code and data have an identical representation" but the important point is that neither of those things is a string. Strings are simply one presentation of code and data, but they're not what Lisp uses internally. In most languages, this distinction is not important, but it's critical for Lisp. If SWE had caught up with Lisp, git for example would be able to produce differences in function definitions, rather than merely in the strings in files that represent those function definitions. That would make git a lot more useful to a Lisp programmer.
- discreteevent 7y agoAlso the reason why for me it's essential to use an editor (usually an IDE) that works with the AST when using other languages. But it's a good point you make. If lisp (or lua tables or any kind of tree) were the base structure for everything instead of bytes it really would be a huge jump up. (There were probably many attempts at this including Charles Simonyi s language based workbench and also in the eclipse world with EMF as the basic tree .. urbit/nock etc etc)
- dreamcompiler 7y agoThis is precisely correct IMHO. Lisp was designed for single programmers managing their entire stack (including the compiler itself) rather than for teams mostly gluing libraries together. Modern software engineering practices are focused on lower-level languages that don't give programmers the power of Lisp. [Herein I mostly mean Common Lisp when I talk about Lisp. I have no experience with large projects in Clojure or Scheme.] Most modern software -- Lisp programs included -- is written by multiple programmers in both coordinated and uncoordinated teams. Lisp can easily adapt to team programming but SWE needs to be augmented to handle programming projects that operate at a meta-level, which is natural with Lisp. If you write code at a meta level with ordinary SWE it can lead to disaster. SWE needs tooling, procedures, and policies to deal with macros, package naming, bootstrapping, multiple-inheritance classes and first-class methods, etc. before it can really support Lisp. Lisp projects that have added such SWE features manually tend to succeed; those that don't tend to have difficulty with Lisp. My point is the team has to do the SWE work; SWE tools operating in default mode tend not to be good enough for Lisp.
- lispm 7y ago> Lisp was designed for single programmers managing their entire stack Funky, McCarthy had a whole team working on and with Lisp.
- dreamcompiler 7y agoSo did Symbolics. And most of those programmers had full-stack mastery. That's not the case with modern software engineering projects. Nor did McCarthy or Symbolics have to deal with the manager-friendly buzzword salad that permeates most software projects today.
- lispm 7y ago> those programmers had full-stack mastery. After many years working in that environment...
- agumonkey 7y agoafter years that's my conclusion, in 50 years people will get it and right now most of the world is slowly migrating to a lisp/ml word without knowing...