[HN Gopher] Lisp.py
       ___________________________________________________________________
        
       Lisp.py
        
       Author : memorable
       Score  : 74 points
       Date   : 2022-07-20 11:17 UTC (11 hours ago)
        
 (HTM) web link (khamidou.com)
 (TXT) w3m dump (khamidou.com)
        
       | peatfreak wrote:
       | I'm wondering about whether using exceptions in the utility
       | functions is misusing Python's exception handling system... Look
       | at is_integer() for example. Is catching ValueError -- if the
       | token cannot be converted -- a Pythonic thing? Or is it abusing
       | exceptions for ordinary (non-exceptional) tokenizing?
        
         | rollcat wrote:
         | Looking at the usage of is_integer, personally I would write
         | something like parse_integer(x: str) -> Optional[int], where
         | the None variant represents a caught ValueError; this avoids
         | parsing the integer twice but achieves basically the same
         | effect (in a very similar style).
         | 
         | What would you propose as "more pythonic" here? Writing your
         | own integer parsing code, by looking at the ASCII values of
         | each character in the string?
        
         | dragonwriter wrote:
         | It's suboptimal and you wouldn't want it for a production
         | interpreter, but it's the lowest friction for leveraging what
         | you get for free with Python to get something working
         | correctly.
        
       | eimrine wrote:
       | Does your implementation has some concept of pairs with car/cdr
       | functions? I am not a true Lisper, just I have started tinkering
       | with it recently.
        
       | ngcc_hk wrote:
       | Scheme in python.
        
       | busterarm wrote:
       | How does one Lisp without TCO?
       | 
       | (Yes, I know some do without, but usually not without a great
       | reason...for example Clojure needing to maintain JVM calling
       | conventions)
        
         | kazinator wrote:
         | Generally, by doing actual work instead of linear recursion
         | exercises.
        
         | fami-com wrote:
         | Common Lisp doesn't guarantee TCO, and yet people manage just
         | fine
        
         | capableweb wrote:
         | One focuses on the learning aspects rather than creating a
         | production lisp. If you want a production lisp, there are
         | plenty out there.
         | 
         | And regardless, adding TCO is relatively simple as well, so not
         | exactly a hard problem to figure out after you've written the
         | first version of your toy lisp.
        
           | busterarm wrote:
           | We're talking about Lisp in Python here. Python itself
           | famously[1,2] refuses to have TCO.
           | 
           | 1: http://neopythonic.blogspot.com/2009/04/tail-recursion-
           | elimi... 2: http://neopythonic.blogspot.com/2009/04/final-
           | words-on-tail-...
        
             | Xophmeister wrote:
             | You can implement TCO in Python manually with continuation-
             | passing style and trampolines.
        
             | capableweb wrote:
             | Here is a lisp implementation (mal) with TCO, written in
             | Python:
             | 
             | - https://github.com/kanaka/mal/blob/master/impls/python/st
             | ep5...
             | 
             | - Theory: https://github.com/kanaka/mal/blob/master/process
             | /guide.md#s...
        
         | rscho wrote:
         | Scheme guarantees TCO, but not Lisp in general I think. I seem
         | to remember that Common Lisp does not guarantee TCO either.
        
       | dTal wrote:
       | This is a very nice example of a literate programming document.
       | It would be amazing if we could adopt this nice ergonomic two-
       | column display style in source files in text editors.
       | 
       | It would be nice if it were clearer how to download the
       | plaintext.
        
       | mark_l_watson wrote:
       | Cool, I bet you had fun with that.
       | 
       | Two random comments: if you haven't played with the Hy language
       | (hylang) it is pretty cool, a surface Clojure like syntax on top
       | of Python. Also, have you tried the Python version of the book?
        
       | madeofpalk wrote:
       | Side note - it's been a while since i've seen a Docco-style
       | annotated-source-style documentation! http://ashkenas.com/docco/
       | 
       | Backbone.js was the first time i saw it, and I loved it!
       | https://backbonejs.org/docs/backbone.html It demonstrated to me
       | that the libraries I use are just normal code that other people
       | write, and i myself can read it to understand a problem.
        
         | abrax3141 wrote:
         | I dislike this style. First off, it's just a block comment.
         | Secondly, although raw markdown isn't terrible to read, it
         | makes it slightly hard to read the actual code as text, say in
         | emacs. But the worst thing is that folks who code like this
         | tend away from inline comments, which I find usually more
         | useful in complex code.
        
           | iLemming wrote:
           | IIRC Docco uses line comments, I'm not sure what your
           | complaint is about. Besides, Emacs has two-column editing
           | mode, making it possible to have side-by-side comments
           | without any external tools. Also, third-party packages like
           | separedit allow comment editing in an indirect buffer. My
           | point is - with little regard for how it's written
           | originally, Emacs (more than any other tool) grants ways of
           | making it suitable for you, personally. You can make things
           | more readable, or optimize them for writing.
        
         | Labo333 wrote:
         | Thanks for the link! I think in that case it was made with
         | https://pycco-docs.github.io/pycco/
        
       | timonoko wrote:
       | I played with python-lisp for some time and decided that python-
       | array is not a LIST but CONS. And if the python-array has more
       | than two pieces, it can be pretty-printed as an ARRAY. Haters
       | will hate, but this is the _Ultimate Solution_.
       | > '[1, 2, 3]         [1, 2, 3]         > '(1 2 3)         (1 2 3)
       | > '[1, 2]         (1  .  2 )         > '[1,(2 3)]         (1 2 3)
       | 
       | https://github.com/timonoko/nokolis.py
        
         | lioeters wrote:
         | > Nokolisp had no strings, but I invented new practise: a flat
         | list of numbers with first number as 34, is prettyprinted as
         | string in the editor. Then you can edit the numberlist normally
         | and the editor shows range(32,256) as chracters alongsside.
         | 
         | Interesting solution! I wasn't sure if you were joking, but I
         | see this syntax/convention is actually used.
         | (print-nice (34 100 101 102 113 40 39))
         | 
         | Is there a way to escape the first number if there's a need to
         | create a list with a literal 34?
        
           | timonoko wrote:
           | Not much need for that. But I would now change the rule so
           | that the number-list must have 34 at both ends. It is little
           | illogical and ugly that there is only one 34 but two
           | quotation marks is prettyprinted.                   > '(34 72
           | 101 108 108 111)         "Hello"
        
       | winrid wrote:
       | Not that it matters for a fun project but there are much faster
       | ways to check if something is an int/float instead of exceptions.
        
         | wjbr wrote:
         | How would you do it?
        
           | dragonwriter wrote:
           | Well, if you've defined valid representation (and if not, you
           | can by just copying the specs from the Python constructor
           | functions you are calling, whose documentation has the
           | definition they support), match to that before calling the
           | conversion function rather than trapping conversion errors.
           | 
           | Even with the exact same representation, it will speed up the
           | no cases at the expense of slightly slowing down the yes
           | cases (assuming that that is also what the function itself
           | does), but since this is called on tokens with no a-priori
           | reason to expect a match as the normal case, you'll have more
           | no than yes, so even if it was symmetric speed swap that'd be
           | a win (and I think the existing way you lose more to each
           | exception that you gain avoiding duplicating the check on
           | matches, so it should be a bigger gain that you'd expect if
           | it was symmetric.)
        
       ___________________________________________________________________
       (page generated 2022-07-20 23:02 UTC)