Live data from Hacker News

Why I still reach for Lisp and Scheme instead of Haskell

jointhefreeworld.org

71–80 of 172 posts

Re: Why I still reach for Lisp and Scheme instead of Haskell

#71
post #34
post #8

> Lisp hackers have been effortlessly reshaping the language for decades using the powerful macro system and extending and bending the language to their will. I've written a bit of Racket code ( https://github.com/evdubs?tab=repositories&q=&type=&language... ) and I still haven't written a macro. In only one case did I even think a macro would be useful: merging class member definitions to include both the type and t…

How do Lisp developers deal with XML and JSON? Convert it to s-expressions. As a common lisp developer, that is only very vaguely true for me. The mapping I prefer for json Lisp is: true: t false: nil null: :null [] #() {} (make-hash-table :test #'equal) This falls out of my desire for the mapping to be bijective: - The only built-in type that is unambiguously a mapping type is hash-tabe. - nil is the only value that…

In Kernel I would use something like this:

    true        #t
    false       #f
    null        ()
    [...]       (& ...)
    "k" : v     (: k v)
    {...}       (@ ...)  
Where &, :, @ are defined as:

    ($define! &
        ($lambda args (cons list args)))

    ($define! : 
        ($vau (key value) env
            (list key (eval value env))))
            
    ($define! @ 
        (wrap 
            ($vau kvpairs env 
                (eval (list* $bindings->environment kvpairs) env))))
Using the "person" example from the JSON/syntax section on Wikipedia:

    ($define! person
        (@
            (: first_name "John")
            (: last_name "Smith")
            (: is_alive #t)
            (: age 27)
            (: address 
                (@
                    (: street_address "21 2nd Street")
                    (: city "New York")
                    (: state "NY")
                    (: postal_code "10021-3100")))
            (: phone_numbers
                (& (@ (: type "home") (: number "212 555-1234"))
                   (@ (: type "office") (: number "646 555-4567"))))
            (: children
                (& "Catherine" "Thomas" "Trevor"))
            (: spouse ())))
I would then define `?`

    ($define! ? $remote-eval)
Now we can query the object.

    > (? age person)
    27

    > (? postal_code (? address person))
    "10021-3100"

    > (car (? children person))
    "Catherine"

    > (cdr (? children person))
    ("Thomas" "Trevor")

    > (? type (cadr (? phone_numbers person)))
    "office"

    > (? number (car (? phone_numbers person)))
    "212 555-1234"

    > ($define! full_name ($lambda (p) (string-append (? first_name p) " " (? last_name p))))
    > (full_name person)
    "John Smith"

Re: Why I still reach for Lisp and Scheme instead of Haskell

#72

> Remember that later, just adding a simple print somewhere is not going to work without refactor (welcome to the IO monad). This hits home for me. Print statements are essential to the way I code. I use them to debug, to examine variables and parameters, to trace execution flow. I rarely use debuggers.

Debug.Trace.trace and friends can help here. This can work from pure code.

But the lazy evaluation does imply that trace functions only execute when the statement is actually forced evaluation. But it is actually quite helpful during debugging..

Re: Why I still reach for Lisp and Scheme instead of Haskell

#74
post #43

> You can pause, inspect objects, change values, and even redefine a broken function on the fly to test a fix in any environment (yes even in production, while running). I see this mentioned often, and it sounds amazingly useful (especially the part about fixing in production!). But how truly widespread is it among the Lisp dialects to be able to connect to a running program, debug, and hotfix it? I understand Common…

That sort of hotfix workflow isn't really a thing in Racket or Scheme in general. Changing the definition of a function doesn't update everything else that calls that function like it does in CL.

Maybe emacs lisp works that way?

Re: Why I still reach for Lisp and Scheme instead of Haskell

#76

> Remember that later, just adding a simple print somewhere is not going to work without refactor (welcome to the IO monad). This hits home for me. Print statements are essential to the way I code. I use them to debug, to examine variables and parameters, to trace execution flow. I rarely use debuggers.

For caveman debugging, if I'm not sitting in a monad, I usually reach for something like Debug.Trace. Typically that's in Idris or my own language, but I see that haskell has it too.

For my own language, I have the syntax highlighting set to put the `trace` keyword in red, so I can easily clean up.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#77

I don't believe monads are a "heavy handed abstraction" and that's what prevents people from prototyping in Haskell. What really prevents people from writing in Haskell at a reasonable speed is the poor language design. Programming languages are supposed to aid in reading by emphasizing structure. It's important to emphasize that a particular group of "words" constitutes a function call, or a variable definition, or…

> It's important to emphasize that a particular group of "words" constitutes a function call, or a variable definition, or a type definition -- whatever the language has to offer.

Syntax highlighting? Please take a look at https://play.haskell.org/

I am completely baffled by this comment. Are you missing the parenthesized function calls by any chance? If so then I can relate a bit.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#78
post #74
post #43

> You can pause, inspect objects, change values, and even redefine a broken function on the fly to test a fix in any environment (yes even in production, while running). I see this mentioned often, and it sounds amazingly useful (especially the part about fixing in production!). But how truly widespread is it among the Lisp dialects to be able to connect to a running program, debug, and hotfix it? I understand Common…

That sort of hotfix workflow isn't really a thing in Racket or Scheme in general. Changing the definition of a function doesn't update everything else that calls that function like it does in CL. Maybe emacs lisp works that way?

Clojure allows for that, giving you neat hot reload capabilities when working in Clojurescript. I believe Emacs Lisp works the same way, and allows for fairly fluid debugging sessions.

Universal hot reload is really a messy beast though. For every "yeah we can just reload this without re-init'ing the structure" there's another "actually reloading causes weird state issues and you have to restart everything anyways" thing.

I've found that hot reloading _specific targetting things_ tends to get you closer to where you want. But even then... sometimes using browser dev tools to experiment on the output will get you where you want faster than trying to hot reload clojurescript but having to "reset" state over and over again or otherwise work around weirdness.

I think this flow works well in Emacs though because you're operating on an editor. So you can change things, press buttons, change things, and have a good mental model. Emacs Lisp methods tend to have very little state to them as well (instead the editor is holding a bunch of exposed state).

Meanwhile React (for example) has _loads_ of hard-to-munge state that means that swapping one component for another inline might be totally fine or might just crash things in a weird way or might not have anything happen. Sometimes just a full page refresh will save you thinking about this

Re: Why I still reach for Lisp and Scheme instead of Haskell

#79

I don't believe monads are a "heavy handed abstraction" and that's what prevents people from prototyping in Haskell. What really prevents people from writing in Haskell at a reasonable speed is the poor language design. Programming languages are supposed to aid in reading by emphasizing structure. It's important to emphasize that a particular group of "words" constitutes a function call, or a variable definition, or…

> (syntax-rules ...) The very first time I tried to use it, I ran into its limitations

syntax-case is the general purpose construct to use. syntax-rules is a restricted, easy-things-should-be-easy construct.

https://www.scheme.com/tspl2d/syntax.html

Post reply on HN