Hacker Newsnew | past | comments | ask | show | jobs | submit | bkirkbri's commentslogin

Same here. I never understood why a paren on the left of a function name “looks like fingernail clippings” but to the right it’s “just how code works.”


We have to try to understand the non-strawman position of those who are genuinely turned off by Lisp syntax. The problem for them isn't the position of the parenthesis or the lack of commas: those things are probably fine for almost everyone.

In Lisps, this notation represents all structures in the program: definitions of functions, types and variables, control statements and so on.

For the users who have some kind of problem with that, it wouldn't be any better with the op(arg, ...) notation; and I suspect that most would agree that it's even worse.

(For that matter, most programmers don't actually have experience nesting the f(x, y, ...) notation to the same depth that is seen in Lisp programs. Anyone comparing a simple one-or-two-liner f(x, y, ...) with a modicum of nesting to Lisp code that runs for pages and pages is doing apples and oranges.)


Clojure takes this criticism to heart, and at least uses different delimiters for indicate different kinds of syntactic structures. Like () for classic lists, [] for arrays, {} for maps. Helps with visually detecting different kinds of structures in your code.


Clojure also prunes the excessive parentheses whenever the structure is obvious from context. E.g. "(let ((a 1) (b 2)) ...)" becomes "(let [a 1 b 2] ...)" and Clojure just requires an even number of elements so that the pairing can be inferred.


Common Lisp has this in the `setq` and `psetq` macros. E.g. exchange `x` and `y`:

  (psetq x y y x)
You can easily have a nesting reduced binding macro, like (var (x 1 y 1) (list x y)), with sequential binding.

Untested:

  (defmacro var (pairs &body body)
    (if (oddp (length pairs))
      (error "~s: variables and init-forms must occur pairwise" 'var))
    `(let* ,(loop for (var init) on pairs by #'cddr
                  unless (and var (symbolp var)
                              (not (eql var t))
                              (not (keywordp var)))
                  do
                    (error "~s: ~s isn't a variable name" 'var var)
                  collect (list var init))
       ,@body)))


Sadly, I'm not convinced that there is much more than the straw man, honestly. Folks are predisposed to think it is a hard to read language. And this is on large because everyone says so.

Similarly, python. Is only a readable language because the community insists it is.


Larry Wall's remark was less about prefix notation and more about how there's very little visual difference. I don't necessarily agree with the criticism because that's the price you pay for homoiconicity, and it's a price well worth paying; but it was a more serious complaint than "lmao parentheses".

See e.g. Clojure, that introduced #{} for sets, [] for vectors etc.


It's funny cause to me visual differences in syntax are just useless information overload. And another dimension of constraints to deal with. That's why I clinged to low syntax languages.. you write in semantics almost. The rest is problem solving (or even extending metadomain with macros or else to help yourself)


>that's the price you pay for homoiconicity

Well no but actually no. Mathematica is homoiconic, and it has tons of special syntax and sugar that all boils down to lists when you quote. Elixir also does this with a ruby-like syntax on top. Those are just the 2 I know of. Making the compiler available through a programmer-accessible API from within the program itself is the big idea, it has nothing to do with what the text grammar happens to be.


Another plus one here. The commas baffle me, as more languages decided to add optional trailing ones...


Recently I’ve been reimplementing some sequencing patches using Scheme for Max and I can say it’s really a joy to use so far. Thank you Iain for making and releasing it. And documenting it!

As someone that loves what Max and Max for Live can do, but prefers a more traditional programming language when implementing complex logic, it really is exactly what I’ve been hoping for. And it’s a Lisp!


Hey, thanks! Did you use the docs on making sequencers? I'm actually working on a whole bunch of new stuff to release for s4m over the next few months (work got paused for a buy/sell/move/renovate ... oof). I could totally do with some more beta testers if you're interested. If you are doing sequencing code in M4L you will definitely like the new stuff. You can reach me at my user name @ giant-email-service-that-starts-with-g.

I will also get a forum up soon so users can share code and stories better. iain


I thought it was a well executed joke myself.


I've found s-expressions to be one of my favorite things about Clojure. I understand that many people dislike them, and that many people get used to them, but I loved the syntax from the get go.


> Being born poor is obviously not a personal choice, but actions taken along the way (having a child when young), taking the risk with illegal and highly addictive drugs, committing violent crime, are conscious acts that unsurprisingly make it harder to get out of poverty. The consequences of those actions is likely particularly known in lower income areas.

I was raised with the same belief, however I have learned through broader experience that people from varying backgrounds have vastly different ways of perceiving and evaluating the information in front of them. I do not mean this to indicate, for example, that people in poverty are inferior and incapable of logically assessing the consequences of a teen pregnancy.

Rather, I would suggest that you and I were likely privy to a myriad of small, incremental and beneficial teachings and experiences that led to our view of teen pregnancy. As a result I believe it unwise to judge others, who did not have the privilege of those same teachings, based on the assumption that they knew the "unsurprising" "consequences" of their actions.


I'm not judging -- I'm stating facts. Also, I was hoping to hint at that policing crime isn't the same as criminalizing being poor. It's possible to be flat out broke and not commit crimes.

Having grown up in a town where the high school graduation rate was below 80%, I can assure you that it's not unfair to expect people from low-income families to know the consequences of their actions.

This is pretty far from my statement of not excusing or ignoring crimes committed by those in poverty, especially violent crimes.


LWT's channels look more like filehandles. I think the GP was asking about channels in the CSP sense. It looks like LWT has that too in the form of streams.


If only the JVM could take advantage of this.


Just about bet you could do that via some grotesque JNI work, but I wouldn't wish JNI on really anyone.


Exciting! I was looking for a ClojureScript monad library just last month. Can't wait to dig in to this one.

I think there is a lot of potential to help with the complexities of asynchronous failures.


We tend to take an in-between approach, baking base AMIs as needed but configuring and installing code with Ansible at boot time. We've got scripts to cut tarballs with an Ansible playbook plus support files from any tag in our repo. Then it's just a matter of specifying the tag in user-data when starting an instance. We do that through CloudFormation.

edit: grammar


This approach has been really helpful for us. We recently open-sourced our Clojure library[1] for running React on Nashorn (the Javascript engine in Java 8). Currently it consumes Hiccup-style markup, but we hope to add Enlive- and Om-style interfaces in the future.

[1] https://github.com/OtherPeoplesPixels/curmudjeon


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: