[HN Gopher] Common Lisp - Myths and Legends (2002)
       ___________________________________________________________________
        
       Common Lisp - Myths and Legends (2002)
        
       Author : susam
       Score  : 53 points
       Date   : 2022-12-22 19:48 UTC (3 hours ago)
        
 (HTM) web link (www.lispworks.com)
 (TXT) w3m dump (www.lispworks.com)
        
       | xigoi wrote:
       | One thing that puts me off about Common Lisp is functions that do
       | multiple different things depending on a flag passed to them.
       | (format nil s) formats a string, whereas (format t s) formats a
       | string _and_ prints it to stdout. This doesn 't look like good
       | design.
        
         | smcn wrote:
         | It makes sense when you understand what it's asking you for.
         | That first argument is you specifying an output destination.
         | For example, would you like to write to an open file, to an
         | open port, to whatever you want. Specifying `t` is the current
         | standard output, whereas nil is you saying "no, just give me
         | the string".
         | 
         | Also, `(format t "str")` does not return a string. At least not
         | on SBCL or CCL.
        
           | medo-bear wrote:
           | thats right. the spec states that if destination is non-nil
           | then format returns nil. otherwise a string
           | 
           | http://www.lispworks.com/documentation/lw50/CLHS/Body/f_form.
           | ...
        
           | xigoi wrote:
           | Still, why not have a function that formats a string and
           | another that outputs it somewhere, instead of one that does
           | two unrelated things?
        
             | atakan_gurkan wrote:
             | Simply, because they are not unrelated. It would be
             | duplication to have two separate functions to do two tasks
             | that have so much in common.
        
               | xigoi wrote:
               | What does formatting a string and sending a string to a
               | file have in common?
        
               | lispm wrote:
               | FORMAT does not send a string to a file.
               | 
               | It executes a program in a domain specific language which
               | creates output to a stream.
               | 
               | This does a bunch of operations. The print functions are
               | being executed on an output stream. If the ARG is NIL,
               | then FORMAT creates a string output stream and later
               | returns the generated string.                 (format nil
               | "~a" 3)
               | 
               | is just short for:                 (with-output-to-string
               | (stream)         (format stream "~a" 3))
               | 
               | ~a is then an operation which writes the argument 3 to
               | the output stream.
        
               | atakan_gurkan wrote:
               | I was replying to your original post, did not notice you
               | posted something different here. Formatting a string and
               | then either returning it or sending it to stdout (or any
               | other stream) has too much in common. The work is done in
               | the formatting, sending is just an after thought.
               | 
               | In a sense, this is similar to the parentheses and the
               | prefix notation: it can be distracting if you are not
               | used to it, but after a while it becomes very convenient.
               | 
               | And I do not mean to sound snobbish, but you can easily
               | write a couple macros to have different syntax for these
               | two tasks if it really bothers you.
        
             | karatinversion wrote:
             | Combining formatting and output is quite common - C has it
             | in the printf family of functions (some of which do not
             | output into anything, but return a string). Similarly,
             | Java's output streams have a format method, which can
             | output to whatever, or fill in an array which you can later
             | convert to a string.
        
             | rovolo wrote:
             | My guess is that it's for efficiency. You have to
             | dynamically allocate a string and then copy it to the
             | destination if you separate "format" and "output". If you
             | combine them, then you can directly output during
             | formatting to your destination. Eliminating this
             | inefficiency while separating "format" and "output"
             | requires some sort of lazy interface or language hack.
        
         | lispm wrote:
         | > (format t s) formats a string and prints it to stdout
         | 
         | FORMAT runs a domain specific language, which causes various
         | print operations to an output stream.
        
         | medo-bear wrote:
         | format is not just a function. it is a domain specific
         | language. it even has a wikipedia entry, all its own. Like it
         | or not, nothing similar exists in any other language
         | 
         | https://en.m.wikipedia.org/wiki/Format_(Common_Lisp)
        
           | gumby wrote:
           | > Like it or not, nothing similar exists in any other
           | language
           | 
           | Uh, what? It's not that different from the printf
           | metalanguage (more powerful, sure, but not that different and
           | inspired by printf)
        
           | xigoi wrote:
           | > format is not just a function.
           | 
           | The article you linked literally starts with:
           | 
           | > Format is a function in Common Lisp...
        
             | nequo wrote:
             | "Not just a function" does not mean that it is "not a
             | function."
             | 
             | But I agree with your original point. "format" is not the
             | most descriptive name for something that "formats and maybe
             | prints."
        
         | kazinator wrote:
         | There is a rhyme and reason to it. There is a stream argument,
         | with the convention that if NIL is used, the stream is an
         | implicit string output stream created for that call, such that
         | the string is returned. And if T is used, then it's a shorthand
         | for standard output. The argument may also be a string with a
         | fill pointer.
         | 
         | This convention isn't just in _format_. It has a name, _stream
         | designator_ :
         | 
         | http://www.lispworks.com/documentation/lw50/CLHS/Body/26_glo...
         | 
         | Other functions like _write_ support the convention.
         | 
         | Moreover there is a broader _designator_ concept at play: there
         | are other kinds of designators.
         | 
         | http://www.lispworks.com/documentation/lw50/CLHS/Body/26_glo...
         | 
         | A designator is some object that by convention stands for
         | another one, under the semantics of some function.
         | 
         | For instance, functional arguments may be function objects or
         | symbols: (mapcar #'list ...) or (mapcar 'list). The list symbol
         | isn't a function, it's a symbol; the reason you can use it as a
         | function is that it's accepted as a function designator. When
         | you call a symbol as a function, it is resolved to the function
         | via its global function binding.
         | 
         | Another kind of designator is the spreadable argument list
         | designator:
         | http://www.lispworks.com/documentation/lw50/CLHS/Body/26_glo...
         | Some functions use this to take a single object or a list in
         | the same argument position. It makes the functions nicer to use
         | in the case when there is just one object, not having to
         | specify the argument as (list arg).
        
           | kagevf wrote:
           | > (mapcar 'list)
           | 
           | Thank you for sharing that, I didn't know that was possible.
           | 
           | I also tried just doing 'list at the repl, and sure enough it
           | gets recognized as a function.
           | 
           | I thought I could break it by doing this:
           | 
           | (let ((list (list 1 2 3)))                  (mapcar 'list
           | list))
           | 
           | I even tried adding on (funcall 'list list) to that block and
           | it still works the same as if I had used (funcall #'list
           | list) ....
           | 
           | I guess it works because the list I bound in the LET isn't
           | referenced as a symbol so FUNCALL etc can distinguish one as
           | a symbol that has a function and the other as the name of a
           | binding ...
           | 
           | Was not expecting these results, so I'll need to review
           | symbols and namespaces ...
        
             | kazinator wrote:
             | You can't break it with LET because functions are in a
             | separate namespace with variables, and because the function
             | lookup done for 'LIST isn't in the lexical scope; it's done
             | inside the mapcar function in another scope, or maybe in a
             | lower-level function like funcall or apply.
             | 
             | Because of separate namspaces, you can't break this either:
             | (let ((list '(1 2 3)))         (mapcar #'list ...))
             | 
             | But the following will break it:                 (flet
             | ((list (x) 42))) ;; actually this is undefined behavior:
             | see below         (mapcar #'list ...))
             | 
             | #'list is (function list) which is lexically resolved, and
             | so it refers to the local function flet. If we use 'list,
             | that is unaffected; it goes to the global one.
             | 
             | This is a bad example because redefining the standard list
             | function in any scope is not well defined behavior.
             | Implementations can allow it or diagnose it. Because it's
             | undefined behavior, implementations don't have to worry
             | about breakage of _list_ uses which occur in macro
             | expansions. E.g. if the syntax `(,foo ,bar) happens to
             | compile to (list foo bar), and your redefinition of list
             | has taken effect in that scope, then that syntax has
             | broken. Oops!
        
               | kagevf wrote:
               | > the function lookup done for 'LIST isn't in the lexical
               | scope; it's done inside the mapcar function in another
               | scope, or maybe in a lower-level function like funcall or
               | apply
               | 
               | Ah, OK, I think that's the key part I was missing ...
               | that explanation also accounts for what I saw in the REPL
               | ... thanks again! :)
        
       | PeterStuer wrote:
       | Personal Edition Limitations
       | 
       | Please note that the LispWorks Personal Edition, distributed free
       | of charge, has the following intentional limitations:
       | There is a heap size limit which, if exceeded, causes the image
       | to exit. A warning is provided when the limit is approached.
       | There is a time limit of 5 hours for each session, after which
       | LispWorks Personal exits, possibly without saving your work or
       | performing cleanups such as removing temporary files. You are
       | warned after 4 hours of use.         The functions save-image,
       | deliver, and load-all-patches are not available.
       | Initialization files are not loaded."
       | 
       | And it is not popular because ...
        
         | Guthur wrote:
         | There is a multitude of very effective free CL implementations.
        
         | mepian wrote:
         | You can get SBCL for free with no limitations which actually
         | beats Lispworks on performance AFAIK: https://www.sbcl.org/
        
           | PeterStuer wrote:
           | Not around the time where it mattered. I loved Lisp, but when
           | our lab moved to an x86 architecture it was Allegro big bucks
           | or nothing.
           | 
           | I was referring to the above pestering of the user base, not
           | that there aren't alternatives.
        
       | gumby wrote:
       | How old is this? Yahoo has surely revamped its code in the past
       | 20 years (if Yahoo stores even exist any more) and John Mallory
       | left MIT decades ago.
        
         | dang wrote:
         | Text from 2002 looks identical: https://web.archive.org/web/200
         | 21105131238/http://www.lispwo.... We've put that in the title
         | above.
        
         | wrs wrote:
         | "Copyright (c) LispWorks Ltd 2000-10"
        
       | yazzku wrote:
       | I like how every Common Lisp website doesn't even have an SSL
       | certificate. Just started learning the language recently and it
       | takes two clicks to get anywhere.
        
       | jgeada wrote:
       | Not expensive? When the reference cost of not hobbled or
       | otherwise limited development environments for almost every other
       | commercial language out there is $0.00, that the _hobbyist_ entry
       | point for LispWorks is $500 is ... more than slightly out of
       | whack. And that LispWorks price is just for the development
       | environment, not for access to a curated store and delivery
       | service or anything else.
       | 
       | Just as well sbcl (Steel Bank Common Lisp) etc exist.
        
         | _ph_ wrote:
         | It was not expensive compared to other commercial Lisp
         | implementations. But the world has moved on and compared to
         | other languages, the prices are unfortunately eye-watering for
         | hobbyists/enthusiasts. Whichs is sad, as Lispworks is a nice
         | environment. I was several times close to getting a personal
         | license, but I just cannot justify it. I can understand that
         | they need to make a living and I am very happy that they are
         | still around. But on the other side, they never managed to get
         | any money from me with their pricing scheme.
         | 
         | I would happily pay the 500 - well at least after a deep breath
         | :p - for a non-commercial license without limits and cross
         | platform, as I would like to use it on the Mac and on Linux,
         | but afterall, I would just use one seat at a time. At these
         | prices, a subscription model might make sense too.
         | 
         | But, as you wrote, there is SBCL+Slime, which is a great
         | environment too. SBCL is even the better compiler.
        
         | eduction wrote:
         | Borland Pascal was $150 in 1983 and considered affordably
         | priced. (Items like linkers used to be sold separately but were
         | integrated into the Borland Pascal development environment,
         | this was seen as a bargain.) Inflation adjusted that's $456
         | today.
         | 
         | I'm not saying I'd spend $500 for this but we are spoiled by
         | all the great free tools today and lose sight of the big
         | picture. Software developers in the US routinely make over
         | $200k/yr. What is $500 for a tool if it really did make you
         | more productive?
        
           | kazinator wrote:
           | > _What is $500 for a tool if it really did make you more
           | productive?_
           | 
           | What is $500 for a tool _to you_ if you make lots of money?
           | Sure, that is one question.
           | 
           | The more relevant question is: what is $500 for the tool, to
           | the tool?
           | 
           | In 2020, what $500 for a tool is a kiss of death. Nobody
           | learns it; no third-party ecosystem, no jobs, ...
           | 
           | OK, you can have some free-with-limitations student or
           | personal editions or whatever. In the FOSS-dominated
           | landscape, that's still a kiss of death. The entire quality
           | and scope depends on the in-house development behind closed
           | doors, which is funded by the $500 licenses.
           | 
           | I think, without the multiple efforts to have free Lisp over
           | the past 3+ decades, Lisp would be history.
        
             | eitland wrote:
             | Microsoft Office, Microsoft Visual Studio and also
             | Jetbrains wants a word with you.
             | 
             | Personally I honestly prefer
             | 
             | - LibreOffice (much better for getting styling consistent
             | last I checked + not spreadsheet is not as obsessed with
             | mangling everything into an American date
             | 
             | - VS Code (less overhead, more ergonomic and seriously: who
             | develops things that needs old Visual Studio these days who
             | hasn't done so for years?)
             | 
             | - NetBeans (yes, I use Jetbrains but only because I have to
             | use Kotlin. NetBeans just works and the shortcuts makes
             | sense to me.)
             | 
             | but that doesn't prevent the above mentioned products from
             | earning lots of (hopefully) well deserved money.
        
               | kazinator wrote:
               | > _Microsoft Office, Microsoft Visual Studio and also
               | Jetbrains wants a word with you._
               | 
               | These days I use LibreOffice on Windows (though very
               | rarely). Microsoft Office isn't free and doesn't come
               | preinstalled, so screw that.
               | 
               | Microsoft Studio has free versions. I have three versions
               | of it on various hard drives; all were free, and with all
               | I was able to produce a program and ship it royalty-free.
        
               | pletnes wrote:
               | Pycharm and VS both have free / hobby versions that is,
               | arguably, of high quality.
        
           | mandw wrote:
           | Turbo Pascal, Turbo C, Turbo Prolog, all things I got at an
           | age when it was just a hobby in high school. In fact I can
           | still look over at my bookshelf and see turbo prolog books..
           | some things you cant bring yourself to throw away!
           | I use SBCL, just for hobby and it does everything I want but
           | I agree that the price is not a lot for the tool if it offers
           | something you want for that amount.               We have got
           | used to not paying for things and its not money we don't
           | have, we have just spent it somewhere else because we have
           | not had to spend it on tools but the price is not over the
           | top - only if you have never had to pay for something.
        
           | richiebful1 wrote:
           | It's in line with what you'd pay for Visual Studio. VS Pro
           | licences are $45 a month and Enterprise licenses are
           | $250/month. It's fair to ask $500 for hobby and $3000 for pro
           | for a perpetual license for LispWorks
        
       ___________________________________________________________________
       (page generated 2022-12-22 23:00 UTC)