[HN Gopher] Why Racket? Why Lisp? (2014)
       ___________________________________________________________________
        
       Why Racket? Why Lisp? (2014)
        
       Author : davikr
       Score  : 137 points
       Date   : 2022-09-14 16:30 UTC (6 hours ago)
        
 (HTM) web link (beautifulracket.com)
 (TXT) w3m dump (beautifulracket.com)
        
       | emmelaich wrote:
       | (2016), according to the comment in the source
        
       | cperkins wrote:
       | It can be difficult to explain why Lisp is so great to non-Lisp
       | programmers. For Lisp, the whole is greater than the sum of the
       | parts.
        
         | macintux wrote:
         | That's true of Erlang as well. The language (and VM) design
         | elements are very complementary.
        
       | eminent101 wrote:
       | > ((if (< 1 0) + _) 42 100)
       | 
       | This gives me an error in SBCL. Error below:                 ;
       | in: (IF (< 1 0)       ;      +       ;      *) 42       ;
       | ((IF (< 1 0)       ;          +       ;          *)       ;
       | 42 100)       ;        ; caught ERROR:       ;   illegal function
       | call       ;        ; compilation unit finished       ;   caught
       | 1 ERROR condition
       | 
       | Why does it not work and how to make it work?_
        
         | moonchild wrote:
         | Common lisp has separate function and value namespaces, unlike
         | scheme. Try (funcall (if (< 1 0) #'+ #'*) 42 100).
        
         | jlg23 wrote:
         | See moonchild's response for the why, here is the how: (funcall
         | (if (< 1 0) #'+ #'*) 42 100)
         | 
         | Edit: this is actually a pretty famous interview question for
         | lisp jobs: write a program that is valid in CL and in scheme
         | but produces different output. The solution is always to use
         | the fact that scheme is a lisp-1, i.e. it has ONE namespace for
         | variables and functions) and CL is a lisp-2, with TWO distinct
         | namespaces.
        
           | sph wrote:
           | Finding out about lisp-1 and lisp-2 when hacking in elisp
           | turned me off so much I've decided to write my own editor in
           | Scheme. This is my personal crusade for the next X months.
        
             | nerdponx wrote:
             | How about using Neovim and writing scripts and configs in
             | Fennel? https://fennel-lang.org/
        
               | sph wrote:
               | vim is great but Emacs is on a whole other level for me.
               | 
               | But I would love to spend some time to write a love2d
               | game in Fennel, for sure.
        
       | nnm wrote:
       | Comment on the functional programming and mutation of data. I
       | learnt R before learnt python.
       | 
       | In R
       | 
       | y = c(1, 2, 3)
       | 
       | x = y
       | 
       | # now x is a copy of y
       | 
       | I was surprised that in python
       | 
       | y = [1, 2, 3]
       | 
       | x = y
       | 
       | # now x is y! What, why?
       | 
       | In R, I am used to the fact everything is an expression:
       | 
       | a = if (x > y) { 0 } else { 1 }
        
         | fspeech wrote:
         | Because it is expensive to copy a large container? Which is why
         | you want immutable data structures, in which case copying is
         | superfluous. So the problem with Python is not the aliasing in
         | assignment, rather it is the mutability of the objects that
         | could create unpleasant surprises.
        
         | fny wrote:
         | R has call-by-value semantics. Python has call-by-reference.
         | These are entirely two different programming paradigms.
         | 
         | https://stackoverflow.com/questions/15759117/what-exactly-is...
        
           | moonchild wrote:
           | Python is not call-by-reference. If it were, we would expect
           | 2 to be printed below, but it is not:                 >>> def
           | f(x):       ...     x = 2       >>> x = 1       >>> f(x)
           | >>> x       1
           | 
           | One might refer to r as being referentially transparent, or
           | immutable (I don't know if it is--I am assuming). I would
           | refer to python as using uniform reference semantics -
           | http://metamodular.com/common-lisp-semantics.html
        
             | fny wrote:
             | I don't expect 2 to be printed. I think you're conflating
             | scope with calling conventions. x is locally scoped to the
             | function. `f` behaves like a lambda/closure.
             | 
             | Would you expect `(define f (lambda(x) x))` to have
             | awareness about some global `x`? The only difference with
             | Python is that the closure has access to the global scope
             | unless the variable is locally defined and a new reference
             | is created in the frame.
        
             | kazinator wrote:
             | What does that Python mean, by the way? The passing of the
             | value into the function is clear enough, but I have no idea
             | whether _f_ is assigning to the local _x_ , or binding a
             | new one.
             | 
             | If we capture a lambda before "x = 2", and then call it
             | afterward, does it see an _x_ which holds the original
             | argument value or which holds 2?
             | 
             | In Lisps, this stuff is clear. Mostly. Except Common Lisp
             | has some areas where it waffles: in some iteration
             | constructs, implementations can bind a new variable or
             | reuse the same one. Those choices are individually clear,
             | though.
        
               | Jtsummers wrote:
               | Creating a new one. It isn't a closure, so:
               | x = 3       def f(x): # note the name here         x = 20
               | f(x)       x # => 3
               | 
               | Similarly, using a different parameter name:
               | def g(y):         x = y       g(20)       x # => 3
               | 
               | You have to explicitly mark the `x` in the function to be
               | the global one to reference it:                 def h(y):
               | global x         x = y       h(10)       x # => 10
               | 
               | With a lambda it would be a closure:                 i =
               | lambda y : x # throwing away y for fun       i(3) # => 10
               | x = 20       i("hi") # => 20
        
               | fny wrote:
               | `f` behaves just like closure. It can even be assigned to
               | a variable.                   def f(x): x = 2 # <- this
               | `x` is the same `x` as in the argument, it can be access
               | via locals() internally
               | 
               | You can even assign `f`. For example, `function = f`.
               | 
               | Python is call by reference. Change my mind. `def f(x):
               | x[0] = 1` will manipulate whatever object you pass to it.
        
               | Jtsummers wrote:
               | If Python were fully call by reference then:
               | def g(y):         y = 3       x = 10       g(x)       x #
               | => ??
               | 
               | If it's 3 then it's pass by reference here, if it's 10
               | it's pass by reference. Which is it?
               | 
               | Additionally, for something to be a closure it has to
               | close over something (an environment). What does `f` or
               | `g` close over? Note that they aren't changing any
               | environment, they are "merely" functions, not closures.
               | Python does have closures, but those aren't examples of
               | them.
               | 
               | And being able to assign a function to a variable does
               | not make a closure, or do you think that C has closures
               | because it has function pointers?
        
       | clusterhacks wrote:
       | A fun essay that really tries to nail down the "Why" in a real-
       | world way.
       | 
       | It mentions that functional programming removes the tripwire of
       | state mutation as one of the "whys", but my experience slightly
       | differs here.
       | 
       | I found, after years of struggling with the "why" of object-
       | oriented programming and its early obsessions with design
       | patterns, that functional programming simply resonated with me
       | personally. To this day, I have a bit of inner cringe when
       | reading (for example) Java code.
       | 
       | Early in my career, I thought my lack of "getting OOP" was due to
       | some profound missing piece of understanding. But then Lisp (and
       | Clojure) _just made sense._ Thinking functionally just works for
       | me. It 's not so much that I couldn't use OOP but just that each
       | time I worked in deeper OOP projects, I felt some internal
       | friction or vague uneasiness with the code.
       | 
       | I did find that functional programming made me significantly more
       | comfortable with OOP languages. YMMV.
        
         | invisiblerobot wrote:
         | Don't stop there.
         | 
         | I thought racket was the holy grail due to the macro system but
         | my real metamorphosis came after learning Haskell. I realize
         | now that my previous preference for Clojure was because I was
         | stuck in prototyping mode.
         | 
         | Once you truly understand your problem domain then types trump
         | macros.
         | 
         | So while I owe a huge debt to Clojure/Racket for rescuing me
         | from my java nightmare, and introducing me to other approaches
         | like Erlang, it was Haskell/Purescript that matured me the most
         | as a programmer.
         | 
         | It was so worth the (considerable) effort, because it has
         | generalized the very nature of computation in a way that just
         | never happened for me in all my years with lisp.
        
         | felideon wrote:
         | Which is funny, because OOP should be[1] about the in-between
         | of the objects: the messages[2]. Not about the objects
         | themselves or the classes and GOF design patterns.
         | 
         | With Common Lisp you get generic functions and design your
         | classes around those.
         | 
         | [1] "OOP to me means only messaging, local retention and
         | protection and hiding of state-process, and extreme late-
         | binding of all things. It can be done in Smalltalk and in LISP.
         | There are possibly other systems in which this is possible, but
         | I'm not aware of them." - Alan Kay (http://userpage.fu-
         | berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay...)
         | 
         | [2] "The key in making great and growable systems is much more
         | to design how its modules communicate rather than what their
         | internal properties and behaviors should be." - Alan Kay
         | (https://wiki.c2.com/?AlanKayOnMessaging)
        
           | k__ wrote:
           | The lecture about GOF design patterns were the first OOP
           | lecture in university where I actually felt I learned
           | something useful.
        
           | deckard1 wrote:
           | It's probably even more humorous if you understand that
           | Scheme was created because Gerald Jay Sussman and Guy Steele
           | wanted a way to experiment with Carl Hewitt's actor model,
           | which is based on message passing. Which, itself, was based
           | on Simula, Smalltalk, etc.
           | 
           | Sussman and Steele came up with a way to do lexical scoping
           | in a LISP, thus closures in LISP were born. They then
           | acknowledged that actors and closures are essentially the
           | same concept (I'm assuming with mutation, i.e. Scheme's
           | "set!" and friends because otherwise message passing to
           | update independent actors would be meaningless).
           | 
           | And to put the cherry on the top, what do Java, Common Lisp,
           | and Scheme all have in common? Guy L. Steele worked on the
           | language specs of all of those. Which makes the dig against
           | Java a bit hilarious, though understandable.
           | 
           | http://people.csail.mit.edu/gregs/ll1-discuss-archive-
           | html/m...
           | 
           | > [...] And by such examples one may be led into the
           | functional style of programming, which is _possible_ within
           | Lisp /Scheme, though not _required_.
        
           | gmfawcett wrote:
           | We should stop invoking Alan Kay's ancient opinion in OOP
           | discussions. I suggest we rebrand his flavour of programming
           | as "message oriented programming" (MOP), thank it for its
           | continuing contributions to the field, and recognize that
           | contemporary OOP is a valid but different solution space.
        
             | felideon wrote:
             | Clarity is certainly important, in which case I could have
             | said "OOP _should have_ been..."
             | 
             | Except: Smalltalk still lives (Squeak) and Erlang takes
             | messaging to the extreme.
        
               | Twisol wrote:
               | I've not used Erlang much, really, but it seems like a
               | really nice fusion of messaging across agents and
               | immutable state within agents. Elixir has long been on my
               | list of languages to properly pick up...
        
             | [deleted]
        
             | samatman wrote:
             | Rather, we should insist on calling object oriented
             | programming what it is, and come up with an acronym for the
             | poor imitations.
             | 
             | How about Class-Reified Abstract Programming? If the shoe
             | fits...
        
               | Existenceblinks wrote:
               | In this era, DeepClass is a kool name.
        
               | gmfawcett wrote:
               | Modern OOP isn't a poor imitation of anything, it's a
               | distinct approach with its own merits. The No True OOP
               | meme is old and tired, and frankly pointless.
        
             | goatlover wrote:
             | Also since Simula proceeded Smalltalk, and C++ is inspired
             | by Simula, and Java by C++.
        
         | ducktective wrote:
         | Show me a GUI framework that follows FP patterns not OOP.
        
           | msk-lywenn wrote:
           | I wonder if dearimgui would count or if it's just imperative
        
           | skruger wrote:
           | https://elm-lang.org/
        
           | hudon wrote:
           | Aside from the all the FP-style GUI frameworks others have
           | listed, it's also worth noting video game development
           | adopting "data oriented design" [0], rather than OOP (usually
           | in C++).
           | 
           | [0] https://www.youtube.com/watch?v=rX0ItVEVjHc
        
           | skruger wrote:
           | https://phoenixframework.org/
        
           | fredrikholm wrote:
           | Off the top of my head:                 * React       * Elm
           | * Halogen       * Phoenix       * Phoenix LiveView       *
           | Re-frame       * Reagent
        
             | fny wrote:
             | Swiftui
        
           | ravi-delia wrote:
           | This is of course a silly but valid criticism of a post
           | claiming FP is better than OOP in every situation. As others
           | have pointed out, there are functional GUI frameworks, though
           | of course something state-heavy is going to be more naturally
           | modeled with OOP in some cases.
           | 
           | But that is all beside the point- OP specifically did _not_
           | claim FP was always better, just that they found it more
           | natural. That personal and subjective experience (which I
           | share) is utterly orthogonal to the relative maturity of GUI
           | libraries! The fact is, most GUI frameworks are OO, and the
           | ones I learned were all OO. And I hated them! I am not a
           | person who enjoys making GUIs, and that 's in large part
           | because I am not a person who enjoys OOP. When I learned my
           | first functional language, it felt like a breath of fresh
           | air. While I was a perfectly serviceable Java and Python
           | programmer, Haskell just made sense _immediately_. That doesn
           | 't make Haskell a better language in absolute terms, but it
           | was much better for me.
           | 
           | Now that I've worked with functional languages, I find I
           | actually don't mind imperative languages at all. I don't
           | really need 100% of the bells and whistles to write
           | composition focused code that meshes with my brain,
           | especially since just a hint of state here or there can free
           | you up to do the rest of it statelessly. And now I find that
           | as I build interfaces with LiveView or Vue that I actually do
           | enjoy making GUIs- even if there is a little state here or
           | there.
           | 
           | People, and this might come as a shock, are sometimes
           | different from each other. And sometimes their talents don't
           | match up perfectly with whatever task you feel is important
           | in the moment. There's lots of programming which isn't as
           | state-heavy as a GUI, just as there's lots of programming
           | more state heavy than a data processing pipeline.
        
         | adamddev1 wrote:
         | Me too. I've also been trying to learn more about OOP and
         | reading "Smalltalk, Objects and Design" bc I heard a lot about
         | how Smalltalk is the real, good OOP. But there were points I
         | just felt squeamish, like when they were talking about the
         | danger of the difference of effect vs. output on methods where
         | I felt anxiety and thinking "ooo, why would I wanna do that??"
         | I can just feel my code getting messier...
         | 
         | Some ideas like using polymorhism to avoid branching
         | conditionals was interesting though and I'm sure there's times
         | it can be helpful.
        
         | bcrosby95 wrote:
         | I'm pretty similar.
         | 
         | People like to ask "why should I use <insert language>?" I
         | never really think about it too much - I don't pull out my
         | weights and measures, and say "well, language X is 83.72%
         | optimal for the problem, but language Y is 91.22% optimal,
         | obviously using language X is a huge mistake!"
         | 
         | If something is obviously better for a problem, I'll pick that
         | language. But if you have to dig too deeply into what language
         | to use, the language probably doesn't actually matter that
         | much.
         | 
         | I was "raised" on OOP, and I "got" it, but I've always
         | preferred more standard procedural programming. I prefer Go
         | over Java, and C over C++.
         | 
         | I like FP more than procedural programming. I prefer Elixir and
         | Haskell over Go.
         | 
         | I like Lispy languages more than other languages. I prefer
         | Clojure over Elixir and Haskell.
        
         | agumonkey wrote:
         | syntax, imperative statements and classical object verbosity
         | and inappropriate structure always hurt me
         | 
         | whenever I read a lisp / ml book, I sweat a bit and then I gain
         | superpowers and insights, whenever I read mainstream OO books I
         | just get a neverending stream of "please stop.. why ??"
         | 
         | and it's not only lisp to be frank but a mindset that lisp
         | embodies a lot.. even using an hp48 felt better than
         | basic+algebraic programming calcs .. (at the time I had no idea
         | what was RPL)
        
         | drnewman wrote:
         | My experience has been exactly the same.
        
         | 13415 wrote:
         | For me, it's the opposite, I like Lisp and Scheme because they
         | don't force me into one programming paradigm. I'm not very fond
         | of FP but used OOP almost in every project when I was
         | programming in Racket (for a decade or so). I often wrote more
         | functional code first and then wrapped it into classes to
         | "assemble" it under one roof.
         | 
         | Lisp and Scheme are great languages for object-oriented
         | programming.
        
           | drnewman wrote:
           | My comments where not at all to make a statement about FP vs
           | OOP, for me they both have their place, and I agree that
           | Lisps are great OOP languages. It just turned out for me that
           | FP came more naturally as a new programmer, and learning
           | about the subtleties of lambda the ultimate, lexical scope
           | and state from an FP perspective helped me to finally feel
           | like I grok OOP. I was pleasantly surprised to see someone
           | else express a similar sentiment.
        
         | FpUser wrote:
         | I am not against / for any reasonable paradigm. I use multiple
         | however I see fit depending on particular situation. Never
         | wanted to be a "purist".
        
           | Tao3300 wrote:
           | Indeed. Sometimes it's more obvious to say "here are the
           | steps to make this thing, now go" and sometimes it's more
           | obvious to say "here's a description of the things I want."
        
         | orangepurple wrote:
         | That friction and vague uneasiness for me is as the nagging
         | thought that it's simply not _correct_ code. In my case I
         | prefer to write as much SQL as reasonably possible to prevent
         | having to write any code in an imperative language.
        
           | klysm wrote:
           | I'm very much in this camp as well. A significant number of
           | applications can be expressed with sql and a thin layer
           | around it
        
             | oedo wrote:
             | +1. And the subset of those applications concerned with
             | simply converting result sets <-> JSON over HTTP may well
             | even tolerate use of an API generator (eg PostgREST,
             | PostGraphile, Hasura), reducing that thin layer to merely a
             | membrane.
        
             | adamddev1 wrote:
             | Interesting. You mean make all the queries as detailed and
             | specific as possible, processing things as much as possible
             | in SQL so you don't have to mess around with the data you
             | get from/put in the DB in an imperative langauge?
             | 
             | Do you have any good examples of this? Code bases that can
             | be read?
        
               | orangepurple wrote:
               | Messing with data significantly outside of SQL is often
               | asking for trouble.
               | 
               | SQL queries are compiled into very efficient operations
               | which would take a lot longer to get right imperatively.
               | Not only that, but database engines are improving all the
               | time, so the same code you wrote which declares your
               | desired transformations tends to get faster over time and
               | there is nothing to update or refactor. The
               | transformations you write are sort of timeless because
               | they are strongly decoupled from the implementation and
               | hardware.
               | 
               | Lots of data transformation steps in imperative languages
               | require the persistence of an intermediate calculation
               | (e.g., np.ndarray). SQL database only do this when the
               | query planner deems it absolutely necessary. It will show
               | up in your query plan as a "materialize" step.
               | 
               | The EXPLAIN feature of SQL is the most useful performance
               | debugging tool. It also alerts me to a potential logic
               | flaw quickly when the proposed plan looks insane. I have
               | personally replaced several analytical programs a very
               | large bank used to monitor loan originations and
               | performance.
               | 
               | I don't use any special SQL language features to this
               | day. The most sophisticated it typically gets is
               | involving lots of subqueries, joins, and window
               | functions. The real skill is distilling the convoluted
               | imperative mess into its essence. I got really good at
               | this.
               | 
               | Half the work effort is usually spent on socializing the
               | changes I have to make to their logic to get it working
               | right in SQL when it changes the behavior of their
               | existing application's logic. Often times I find the
               | client's imperative code attempting to perform a logical
               | operation such as a join but it is implemented
               | incorrectly.
               | 
               | Their existing imperative code operations actually
               | produced the wrong results (subtly) frequently or their
               | imperative code depended on the order of the data
               | returned from the database (undefined behavior). Yikes.
               | 
               | What they actually wanted was provably implemented
               | incorrectly or relied on undefined behavior and their
               | mistakes and the proper resolution in SQL could be easily
               | verified with paper and pen on a sample set of loans if
               | necessary to drive the point home.
        
               | adamddev1 wrote:
               | Very cool. So you write it with _solid, declaritive SQL_
               | and you can trust that it will be rock solid and
               | optimizied. Need to learn SQL instead of just doing NoSQL
               | all the time. Thanks for the explanations.
        
               | orangepurple wrote:
               | I load JSON into Postgres all the time these days for
               | analyzing data for a government client and use Postgres
               | JSONB operators to untangle and index it. JSONB because I
               | don't care about preserving the original string
               | representation of the record (strings in fields are still
               | completely intact).
               | 
               | Although I heavily lean on psql with \COPY and stdin or
               | stdout pipes to a compressor like zstd (psql can natively
               | pipe CSV to and from any program reliably even in
               | Windows) I found loading JSON records to be extremely
               | frustrating this way.
               | 
               | Whatever you do NEVER use pipes in Powershell. They don't
               | stream. They buffer in RAM fully into your computer
               | crashes. Microsoft is insane.
               | 
               | Since you use NoSQL you can write a very short Python
               | program that uses psycopg2 directly to load a list of
               | dict as JSONB rows into a single Postgres table with one
               | column (I call mine "record")
               | 
               | At that point you can basically use Postgres as a NoSQL
               | database and structure the records _if you want_ using a
               | VIEW.
               | 
               | We're in the process of documenting their use of JSON for
               | financial records keeping as a design defect.
        
               | ithrow wrote:
               | _Their existing imperative code operations actually
               | produced the wrong results (subtly) frequently or their
               | imperative code depended on the order of the data
               | returned from the database (undefined behavior). Yikes._
               | 
               | That just sounds like very sloppy programming.
        
       | tombert wrote:
       | I think Racket is pretty awesome, but I will admit that I think
       | Clojure is a ten times easier sell. The value of being able to
       | interop with existing JVM languages really cannot be overstated,
       | and it makes employers substantially easier to buy in.
       | 
       | That said, when I'm doing personal projects, I don't particularly
       | care about what my employers think...but I still prefer Clojure.
       | I think the native hashmap data type makes it just an
       | exceptionally appealing Lisp, and I find that the language never
       | gets in my way.
        
       | abrax3141 wrote:
       | Maybe when the same URL is posted again in HN, the platform
       | should automatically insert a first post with links to the
       | previous discussions, as someone did here. It's not irrelevant to
       | repost, but it could be useful to have pointers to previous
       | conversations. Similarly, the platform could warn the poster that
       | its a repost (a bit like stackoverflow does, but simpler - just
       | using link equality).
        
       | dang wrote:
       | Related:
       | 
       |  _Why Racket? Why Lisp?_ -
       | https://news.ycombinator.com/item?id=28966533 - Oct 2021 (2
       | comments)
       | 
       |  _Why Racket? Why Lisp?_ -
       | https://news.ycombinator.com/item?id=19952714 - May 2019 (122
       | comments)
       | 
       |  _Why Racket? Why Lisp?_ -
       | https://news.ycombinator.com/item?id=15473767 - Oct 2017 (1
       | comment)
       | 
       |  _Beautiful Racket: Why Racket? Why Lisp?_ -
       | https://news.ycombinator.com/item?id=13884234 - March 2017 (7
       | comments)
       | 
       |  _Why Racket? Why Lisp? (2014)_ -
       | https://news.ycombinator.com/item?id=9268904 - March 2015 (164
       | comments)
       | 
       |  _Why Racket? Why Lisp?_ -
       | https://news.ycombinator.com/item?id=8206038 - Aug 2014 (280
       | comments)
        
       | revskill wrote:
       | Enough praise for FP. Now let's go back to real world.
       | 
       | Please help tell me what's the best way to replicate what's good
       | in OOP, like how to use FP to solve expression problem ?
        
         | deltasevennine wrote:
         | OOP is a mass delusion not dissimilar to religion.
        
         | [deleted]
        
         | BeetleB wrote:
         | I can understand the pushback against FP, but it doesn't follow
         | that if FP is a poor choice, then the only realistic
         | alternative is OOP.
         | 
         | I do a lot of Python stuff - much of it is not functional
         | programming. And very little of it is OOP.
         | 
         | The programming world doesn't consist of just these.
        
         | hither_shores wrote:
         | > like how to use FP to solve expression problem
         | 
         | Some common approaches:
         | 
         | - Tagless final style: https://okmij.org/ftp/tagless-final/
         | 
         | - Datatype-generic programming:
         | https://markkarpov.com/tutorial/generics.html
         | 
         | - Polymorphic records and variants:
         | https://www.cl.cam.ac.uk/teaching/1415/L28/rows.pdf
        
           | Twisol wrote:
           | I'm a very big fan of the "object algebras" approach [0],
           | which is essentially tagless final minus the automatic
           | instance resolution you get with typeclasses. It works great
           | even in fairly restrictive type systems like Java's.
           | 
           | [0]:
           | https://www.cs.utexas.edu/~wcook/Drafts/2012/ecoop2012.pdf
        
         | panzerklein wrote:
         | Expression problem exists in both OOP and FP[1]
         | 
         | [1] https://wiki.c2.com/?ExpressionProblem
        
       | flipflip wrote:
       | I love racket. It helped me understand the concept of limited
       | continuations and macros.
        
       | myth_drannon wrote:
       | From the article - "[2021 update: I no longer contribute to
       | Racket due to abuse & bullying by the project leadership.
       | Everyone in the broader Racket community, however, has always
       | been helpful and kind.]"
        
         | waynesonfire wrote:
         | maybe the author was the bully? i don't see how it's helpful to
         | perpetuate hearsay especially without any context.
        
           | michaelwww wrote:
           | https://beautifulracket.com/appendix/why-i-no-longer-
           | contrib...
        
             | eternalban wrote:
             | He actually attributes malicious intent ("campaign") to
             | this other person. Based on no evidence whatsoever, just
             | feelings apparently. The apology was gracious, forthright,
             | and entirely believable. The guy is uptight and blows up.
             | Does that make him a "bully" who "campaigns" to harrass
             | other people?
        
           | throwaquestion5 wrote:
           | There is context, if you just open the article and see the
           | link in the same sentence. But I guess is asking too much
        
         | BeetleB wrote:
         | Let's not derail the discussion.
         | 
         | To be clear, the author still continues to use Racket. His
         | statement is more about his contributions and evangelizing.
        
       | neilv wrote:
       | The article mentions X-expressions for XML and HTML. If you
       | decide to play with that, you might also want to look at another
       | representation, SXML, which has more advanced library support in
       | the Racket ecosystem.
       | 
       | https://docs.racket-lang.org/sxml-intro/index.html
       | 
       | (Basically, early in Scheme, there were a bunch of independently-
       | invented representations for XML. It turned out that Oleg
       | Kiselyov's XML parsing work, SSAX, was better than anyone else's.
       | So I converted my libraries to be compatible with his SXML
       | representation, and others also built tools using SXML. But core
       | Racket (then called PLT Scheme) seemed stuck with X-expressions.
       | Today, one of the core Racket professors maintains the Racket
       | packaging for Oleg's SXML libraries, but it's contrib rather than
       | core. People starting with the core docs might only hear of
       | X-expressions, until they start searching the contributed package
       | directory, and find those packages generally use SXML.)
        
         | uneekname wrote:
         | And shout-out to you, Neil, for maintaining a lovely HTML
         | parser for Racket. You recently pushed an update to help me
         | with a project of my own.
        
       | michaelwww wrote:
       | After years of reading Lisp articles, my take is that the macro
       | system is what sets Lisp languages apart. I was surprised then
       | that the author didn't find them that useful.
       | 
       |  _[Paul Graham] describes Lisp as his "secret weapon". OK, so
       | what's the secret? He says "programming languages vary in power".
       | Fine, but what exactly makes Lisp more powerful? ...Lisp's macro
       | facility, which he describes as its ability to make "programs
       | that write programs". After four years using a Lisp language, I'd
       | agree with Graham that macros are great when you need them. But
       | for someone new to Lisp languages, they're not necessarily a
       | bread-and-butter benefit._
       | 
       | Further down...
       | 
       |  _Paul Graham calls Lisp a "secret weapon". I would clarify: Lisp
       | itself isn't the secret weapon. Rather, you are--because a Lisp
       | language offers you the chance to discover your potential as a
       | programmer and a thinker, and thereby raise your expectations for
       | what you can accomplish._
       | 
       | What's the secret weapon if it isn't macros? I know what I need
       | from a language that matches my particular quirks as a programmer
       | and helps me shine and it's not Lisp.
       | 
       | This article made me interested in Racket's libraries because it
       | sounds like they might be more interesting than other languages
       | libraries.
        
         | felideon wrote:
         | > I know what I need from a language that matches my particular
         | quirks as a programmer and helps me shine and it's not Lisp.
         | 
         | Yes, but the argument is that, once you've experienced Lisp,
         | your quirks as a programmer completely change. It might not be
         | so much that you need to decide whether you need macros.
         | Instead, decide whether there might be a different approach to
         | writing code that could let you express yourself more
         | naturally. See PG's essay on Programming Bottom-up.[1]
         | 
         | [1] http://paulgraham.com/progbot.html
        
         | mikelevins wrote:
         | I don't think that macros are the singular thing that sets
         | Lisps apart. I do think that they're an extremely useful
         | feature to have, especially if you build programs and systems
         | by building languages in which to express them.
         | 
         | Lisp's macros are a way to define a syntax that you would like
         | to be able to use, and arrange for Lisp to rewrite that syntax
         | into something that Lisp already supports.
         | 
         | Two circumstances where they come in really handy are:
         | 
         | 1. You have to repeatedly write a bunch of boilerplate that
         | never changes, except for maybe a few small particulars. You
         | can write a macro to turn all that boilerplate into a succinct
         | expression that writes the boilerplate for you. As an example,
         | DEFCLASS can be implemented as a macro that writes all of the
         | low-level machinery of setting up a class and all its
         | appurtenances so that you don't have to.
         | 
         | 2. You need to write some code that is error prone in some way,
         | and you want to ensure that relevant protective or recovery
         | measures are never ever forgotten. You can write a macro that
         | writes the protective or recovery measures for you around the
         | error-prone code. As an example, WITH-OPEN-FILE is a macro that
         | ensures that an opened file is properly closed, no matter how
         | control exits the WITH-OPEN-FILE form.
        
         | openfuture wrote:
         | Not everything is about secret weapons... it is just simple and
         | clear to use S-expressions, people like simple and clear.
        
         | runevault wrote:
         | I took the first quote as you need to hold a certain amount of
         | comfort with lisp before macros matter, not that they aren't an
         | incredible once you understand everything well enough to use
         | them.
        
           | michaelwww wrote:
           | A couple of people were nice enough to take the time to
           | explain Lisp macros to me in case you're interested:
           | https://news.ycombinator.com/item?id=32730470
           | 
           | I can definitely see their power, but I don't have any ideas
           | on what I would do with them. I guess I'd have to write Lisp
           | for awhile to figure that out.
        
             | runevault wrote:
             | One way to think about macros is custom syntactic sugar
             | that you can build yourself. So for example, I don't think
             | rust has parameter array (see params/param arrays in c# for
             | an example [1]). So for things like their println that
             | takes variable number of strings to inject into the string
             | where it finds {} it uses the println! and format! macros.
             | Because the parser doesn't support the sugar of a comma
             | separated list and turning that into an array the way c#
             | does (or however other languages handle the same idea), the
             | macro pass of the compiler instead generates the code
             | necessary to make that number of arguments work.
             | 
             | There are likely other uses I've never considered, but that
             | is a simple one.
             | 
             | [1]: https://docs.microsoft.com/en-
             | us/dotnet/csharp/language-refe...
        
             | BeetleB wrote:
             | This article is an appendix for the online book Beautiful
             | Racket, and most of the book is about how useful macros can
             | be. It's a very accessible book - not at all advanced.
             | 
             | A number of folks have listed the book as one of their best
             | all time programming books. I finally read it last year,
             | and I agree with that characterization. It's a very well
             | written book.
        
             | qazwse_ wrote:
             | This is the case for me as well. I was learning Common Lisp
             | for fun, and I loved it, but macros never clicked for me. I
             | could understand how they're powerful, but I never
             | developed a sense for when using a macro would make things
             | easier. Probably just not enough time with the language.
        
       ___________________________________________________________________
       (page generated 2022-09-14 23:00 UTC)