30 ms·
Show HN: Bel
- dangrossman 7y agoWelcome back to Hacker News
- wtvanhest 7y agoIts been a long time!
- giancarlostoro 7y ago"Its you... Its been a long time. How have you been?" - GLaDOS (Portal 2)
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- jmccarthy 7y agoOpen to sharing a bit about the name? No mention of it in the guide.
- cperciva 7y ago"Characters that aren't letters may have longer names. For example the bell character, after which Bel is named, is \bel"
- photon-torpedo 7y agoMy guess would have been a short for BEtter Lisp ;-)
- Koshkin 7y agoI’ll wait for lim.
- gus_massa 7y agoJust guessing. His previous language is called arc, it has three letters and starts with an \a.
- Koshkin 7y agoI am not convinced - ‘\a’ had already been taken by C.
- deleted 7y ago[deleted]
- cperciva 7y agoIs there a version of Bel written in some other language? If not, how do you get started without a bootstrap?
- npstr 7y agoAs mentioned in the user guide, just like Lisp, Bel is still in its formal phase, and not usable as a programming language yet. The idea is to extend the formal phase for a longer time, before diving into the implementation.
- drcode 7y agoHe uses an unreleased interpreter he wrote for it in arc.
- dfischer 7y agoJust when I was curious on learning some Lisp. I was also saddened how much it's dropping on https://www.tiobe.com/tiobe-index/ https://www.tiobe.com/tiobe-index/
- erik_seaberg 7y ago“Lisp doesn't look any deader than usual to me.”—David Thornley via http://www.paulgraham.com/quotes.html http://www.paulgraham.com/quotes.html
- intricatedetail 7y agoBit Edgy Language? Nice work!
- whazor 7y agoWelcome back pg. You should check out Jetbrains MPS, they are doing cool stuff with projectional editing. Which could mean no more brackets. I read via Twitter that they recently announced MPS for Web in Amsterdam yesterday, unfortunately I missed the conference because of my home situation :). Luckily they filmed the presentations so I will be waiting for them on YouTube.
- applecrazy 7y agoI can't say I'm familiar with Lisp (or its dialects). How does one get started learning a Lisp variant (in terms of learning resources/guides), and why use Lisp over other languages?
- sincerely 7y agoScheme is the teaching version of Lisp that gets used in a lot of first year university CS classes, you can probably work through an online syllabus pretty quickly if you have experience in another language.
- aasasd 7y agoIn my experience: just pick one that you'll be using, e.g. Emacs Lisp or something for scripting, and dive into practice. Most of a lisp is little different from other imperative-functional languages, except for a taste of weirdety from the 60s and more functional freedom. You could pick something like ClojureScript if you're using JS elsewhere―in the Lumo incarnation to avoid JVM's compilation and startup time. Though ClojureScript does add a level of complication. Other transcompiling variants like Fennel or Hy are also feasible but are probably poor on documentation and tools for a beginner.
- dreamcompiler 7y agoGet a copy of The Little Schemer and follow it step by step in Racket, which is freely downloadable. It is better when learning to experience Lisp in this way than to read an explanation of why Lisp is good. It activates a different part of your brain. For many people, it feels like a dormant part of your brain has just awakened for the first time.
- cylinder714 7y agoAs I understand it, Scheme was intended to be a dialect suitable for teaching programming. The usual first texts are The Little Schemer, How to Design Programs (https://htdp.org/ https://htdp.org/ but apparently a third edition is forthcoming: https://felleisen.org/matthias/HtDP3e/index.html https://felleisen.org/matthias/HtDP3e/index.html) and the inestimable SICP: http://sarabander.github.io/sicp/ http://sarabander.github.io/sicp/ (HN discussion: https://news.ycombinator.com/item?id=13918465 https://news.ycombinator.com/item?id=13918465) "A bad day writing code in Scheme is better than a good day writing code in C." —David Stigant In another man's opinion, "Common Lisp is the best language to learn programming": https://oneofus.la/have-emacs-will-hack/2011-10-30-common-lisp-is-the-best-language-to-learn-programming.html https://oneofus.la/have-emacs-will-hack/2011-10-30-common-li... Another resource for learning Common Lisp is Stuart C. Shapiro's Common Lisp: An Interactive Approach: https://cse.buffalo.edu/~shapiro/Commonlisp/ https://cse.buffalo.edu/~shapiro/Commonlisp/
- markhowe 7y agoThere’s no link styling, at least on mobile Safari, they’re kind of essential to understand the article. ...sorry to be that guy.
- npstr 7y agoSame on Android Chrome.
- dang 7y agoPending a fix, here are the links. (Edit: should be fixed now.) The way Lisp began: http://paulgraham.com/rootsoflisp.html http://paulgraham.com/rootsoflisp.html A guide to the Bel language: https://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt?t=1570864329& https://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt?t=157... The Bel source: https://sep.yimg.com/ty/cdn/paulgraham/bel.bel?t=1570864329& https://sep.yimg.com/ty/cdn/paulgraham/bel.bel?t=1570864329& Some code examples: https://sep.yimg.com/ty/cdn/paulgraham/belexamples.txt?t=1570864329& https://sep.yimg.com/ty/cdn/paulgraham/belexamples.txt?t=157...
- arketyp 7y agoHow does this relate to Arc?
- pg 7y agoThe code I wrote to generate and test the Bel source is written in Arc, and Bel copies some things from Arc. Otherwise they're separate.
- _emacsomancer_ 7y agoHow is it an improvement over Arc? What issues does Arc have that Bel solves/addresses?
- pg 7y agoIn the same way it's an improvement over other Lisp dialects. There's no huge hole in Arc that Bel fixes. Just a lot of things that are weaker or more awkward or more complicated than they should be.
- breck 7y ago> The code I wrote to generate and test the Bel source is written in Arc Was this during bootstrapping, or is this still the case? Or in other words, do you now edit bel.bel directly or are there arc files you edit that compile into bel.bel?
- pg 7y agoIt's still the case. bel.bel is generated by software. Most of the actual code is Arc that I turn into Bel in generating it. E.g. the interpreter and anything called by it, and the reader. But code that's only used in Bel programs, rather than to interpret or read Bel programs, can be and is written in Bel. I had to change Arc a fair amount to make this work. Curiously, enough, though, I found doing development in Bel was sufficiently better that I'd often edit code in bel.bel, then paste a translated version into the file of Arc code, rather than doing development in the latter. This seemed a good sign.
- daoudc 7y agoI love the idea of trying to build a mathematically pure language. I wonder how far it is possible to use optimisation techniques to make Bel efficient. For example, can the representation of strings as pairs be automatically optimised to a sequence of characters?
- repolfx 7y agoYes, I believe lisps virtually always do that in practice, as does Haskell if you use certain string types (fp languages have their roots to lisp even though they have different syntax). But lisps are dynamically typed, so to make them run fast you'd need to use a speculating jit compiler like GraalVM. They're more like python, performance wise without it.
- pg 7y agoOne thing you can say for Bel for sure is that it will give implementors lots of opportunities to develop new optimization techniques. That's partly humorously euphemistic, but also true.
- deleted 7y ago[deleted]
- m0zg 7y agoWish I could have Lisp without all the parentheses. Parentheses just sour the experience for me.
- 97b683f8 7y agoThis probably means your "experience" of lisp was very short.
- m0zg 7y agoIt admittedly is, just as it is for most other people: there are very few "serious" prorgams I can name that were written in Lisp, in spite of its venerated heritage. There's no shortage of options in the programming language field, so one would be a fool to stick with a language they don't enjoy working in.
- dang 7y agoThe parens are the shadow cast by Lisp's consistency, which is the reason to wish for Lisp in the first place. The solution is not to look at the parens. It's a bit like not listening to tinnitus, which is harder for some than for others. Tools help.
- loevborg 7y ago> The parens are the shadow cast by Lisp's consistency, which is the reason to wish for Lisp in the first place. Beautiful. I'm stealing that, with your permission?
- dang 7y agoSure. But you should steal it without permission.
- m0zg 7y agoI get that, but I can't help but view them as visual noise.
- SudoNhim 7y agoExciting! This has a lot in common with Nock/Hoon
- joak 7y agoI do not see any text file... Must be hidden somewhere or not showing in my browser (firefox android with ad blockers)
- imdhmd 7y agoThere are links. They are hard to get to because of lack of link styling.
- dang 7y agohttps://news.ycombinator.com/item?id=21231348 https://news.ycombinator.com/item?id=21231348
- msravi 7y agoI think the mobile site doesn't show the links for some reason. If you click on the "View full site" link at the bottom, the links show up.
- ajju 7y agoIt’s great to see a technical post from pg after a while!
- imdhmd 7y agoI am unable to understand the difference between (a b c) and (a b . c)
- SamReidHughes 7y ago(a b c) is (a b c . nil). That is, (a . (b . (c . nil))). On the other hand, (a b . c) is (a . (b . c)). (Edit: rewrote post)
- imdhmd 7y ago() is equivalent to an empty list and nil according to this notation, in which case both would be proper lists. But according to pg, in bel, (a b . c) is not a proper list. Edit: I think I understand now, hmm.
- erik_seaberg 7y agoThink of a proper list like a degenerate tree with all the values on the left and structure on the right. A dotted list puts the last value on the right, where nil would usually be. Dotted lists are pretty rare. They mostly show up in association lists, where key/value pairs are stored as ((name . dave) (type . user)) and adding a pair to the front of the list shadows any other pairs with the same key.
- nilkn 7y agoWhile I think this is the correct interpretation, I do not think it's actually implied by the language specification. In fact, I think the notation (a b . c) is simply undefined -- there's no way to formally deduce what it means from what is defined.
- SamReidHughes 7y ago> 2. When the second half of a pair is a list, you can omit the dot before it and the parentheses around it. So (a . (b ...)) can be written as (a b ...). That defines (a b . c). Edit: Note that (b . c) is a list.
- mrburton 7y agoPG is still alive and coding! :)
- deleted 7y ago[deleted]
- lostmsu 7y agoOn mobile Firefox links are indistinguishable from regular text. Workaround is to view full site (link at the bottom)
- dang 7y agoHopefully there will be a fix soon. In the meantime see https://news.ycombinator.com/item?id=21231416 https://news.ycombinator.com/item?id=21231416.
- shpx 7y agoIf Bel doesn't have irrational numbers, how do I use pi? Define a function that returns an approximation to a given precision?
- pubby 7y agoI'm curious how you use irrational numbers in any language. I'm not aware of any mainstream languages that support them.
- shpx 7y agoIn Python there's SymPy. It simplifies expressions and then you can ask for the answer as a number to N decimal places. >>> from sympy import N, sqrt, pi >>> N(sqrt(2)*pi, 50) 4.4428829381583662470158809900606936986146216893757 https://docs.sympy.org/latest/modules/evalf.html https://docs.sympy.org/latest/modules/evalf.html https://en.m.wikipedia.org/wiki/Computer_algebra https://en.m.wikipedia.org/wiki/Computer_algebra
- kccqzy 7y agoThat's a crude approximation of what Mathematica can do. Not all (in fact, very few) irrational numbers are computable. Yet among the computable numbers, what our computers can represent in any language is but a small subset of them. (Although computable numbers are equinumerous with the naturals.)
- black_knight 7y ago> Yet among the computable numbers, what our computers can > represent in any language is but a small subset of them. This is only true because of physical limitations of the machine (say, it has only finite memory). In the same way not all Turing machines cannot be implemented on actual computers. This is not a restriction of the languages we use. There is nothing stopping an actual programming language representing all computable real numbers. > (Although computable numbers are equinumerous with the naturals.) This is only true in classical mathematics. In constructive mathematics we are free to assume that all real numbers are computable (And hence, not equinumerous with the naturals, per cantor’s argument).
- p4bl0 7y agoIt's strange that the description of the language [0] starts using numbers without introducing them at first and then far later in the file says that they are implemented as literals. I didn't get to see the source code yet (I'm on mobile and have to randomly tap the text of the linked article to find links…), but I don't understand the point of this nor if it's just a semantic choice or actually implemented that way (I don't see how). [0] https://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt?t=1570864570& https://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt?t=157...
- lewisjoe 7y agoWelcome back PG! HN: How do you get an intuitionistic understanding of computation itself? While Turing Machines kind of make sense in the context of algorithms, can I really intuitively understand how lambda calculus is equivalent to Turing machines. Or how Lambda Calculus can solve algorithms? What resources helped understanding these concepts? I'm currently following http://index-of.co.uk/Theory-of-Computation/Charles_Petzold-Annotated_Turing-Wiley(2008).pdf http://index-of.co.uk/Theory-of-Computation/Charles_Petzold-... and a bunch of other resources in the hope I'll "get" them eventually.
- whoeverest 7y agoI can share my experience, because I was asking myself the same question 6 years ago... My approach was to try and build a Lisp -> Brainfuck compiler. My reasoning was: Brainfuck is pretty close to a Turing machine, so if I can see how code that I understand gets translated to movement on a tape, I'll understand the fundamentals of computation. It became an obsession of mine for 2 years, and I managed to develop a stack based virtual machine, which executed the stack instructions on a Brainfuck interpreter. It was implemented in Python. You could do basic calculations with positive numbers, define variables, arrays, work with pointers... On one hand, it was very satisfying to see familiar code get translated to a large string of pluses and minuses; on the other, even though I built that contraption, I still didn't feel like I "got" computation in the fundamental sense. But it was a very fun project, a deep dive in computing! My conclusion was that even though you can understand each individual layer (eventually), for a sufficiently large program, it's impossible to intuitively understand everything about it, even if you built the machine that executes that program. Your mind gets stuck in the abstractions. :) So... good luck! I'm very interested to hear more about your past and future experiences of exploring this topic.
- thisBrian 7y agoQuite intrigued with your approach; will look into trying something similar for visualising an embedded system.
- dorfsmay 7y agoAre you aware that GNU Guile, which is self hosted (written mainly in scheme), can interpret brainfuck? https://www.gnu.org/software/guile/manual/guile.html#Supporting-Multiple-Languages https://www.gnu.org/software/guile/manual/guile.html#Support...
- rayalez 7y agoWow! So cool to see a new post from PG! Really curious to see what this project will become.
- neya 7y agoWelcome back Paul :) Great to hear from you again. I almost thought you were too busy for HN since you became less active here, it's really nice to see you again!
- PostOnce 7y agoIt amuses and pleases me to see that pg will continue to play around with lisp presumably forever, regardless of how wealthy he becomes. I hope I'll never stop coding passion projects myself. John Carmack talked about this on Joe Rogan's show recently, about how he still codes and how Elon Musk would like to do more engineering but hasn't much time. I wonder if Bill Gates ever codes anything anymore, I emailed to him ask once but never got a reply. Tim Sweeney is a billionaire and still knee deep in code. It's Saturday night here, and I'm going to go write some code. Unproductive, unprofitable, beautiful game engine code. Hope all you other hackers get up to something interesting this weekend.
- golemiprague 7y agowe got life you know
- p4bl0 7y ago> regardless of how wealthy he becomes It may be the reverse that happens here: he is wealthy enough to have time to play with Lisp.
- dang 7y agoHe was playing with Lisp before he was wealthy and also while becoming wealthy. HN's software, which runs on Arc, used to run YC too. It was all one codebase. Only after pg retired did YC move the business parts of the software out of Lisp, and it got a lot bigger and more complicated in the process—as any Lisper would expect.
- pg 7y agoAt first it was not just all one codebase, but all one thread. If HN was busy, all our internal software would run a little slower.
- mattknox 7y agohave you thought about publishing the full source from then? The HN source was dense but very educational, and it would be really interesting to see internal tools written in arc.
- dang 7y agoSome users are reporting that the links don't show up on some mobile browsers. Pending a fix, here they are. (Edit: fixed now.) The way Lisp began http://paulgraham.com/rootsoflisp.html http://paulgraham.com/rootsoflisp.html A guide to the Bel language https://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt?t=1570864329& https://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt?t=157... The Bel source https://sep.yimg.com/ty/cdn/paulgraham/bel.bel?t=1570864329& https://sep.yimg.com/ty/cdn/paulgraham/bel.bel?t=1570864329& Some code examples https://sep.yimg.com/ty/cdn/paulgraham/belexamples.txt?t=1570864329& https://sep.yimg.com/ty/cdn/paulgraham/belexamples.txt?t=157...
- rntz 7y ago> 5. (where x) > Evaluates x. If its value comes from a pair, returns a list of that pair and either a or d depending on whether the value is stored in the car or cdr. Signals an error if the value of x doesn't come from a pair. > For example, if x is (a b c), > > > (where (cdr x)) > ((a b c) d) That is one zany form. 1. How is this implemented? 2. What is the use of this? 3. What does (where x) do if x is both the car of one pair and the cdr of another, eg. let a be 'foo, define x to be (join a 'bar), let y be (join 'baz a), and run (where a).
- pg 7y agoIt's used to implement a generalization of assignment. If you have a special form that can tell you where something is stored, you can make macros to set it. E.g. > (set x '(a b c)) (a b c) > (set (2 x) 'z) z > x (a z c) which you can do in Common Lisp, and > (set ((if (coin) 1 3) x) 'y) y > x (y z c) which you can't.
- soulofmischief 7y agoThanks for sharing, Paul. Still knee-deep in the source. Gonna steal some of this. What made you settle on (coin), is that a LISP trope? I flopped back and forth between naming it (coin) and (flip) in my own LISP before finally settling on (flip). I'd honestly like to divorce the name entirely from its physical counterpart.
- defen 7y ago> I'd honestly like to divorce the name entirely from its physical counterpart. How about (bit) or (randbit)
- soulofmischief 7y ago(randbit) isn't bad. My implementation also takes a float 0 <= x <= 1 to determine the probability of the outcome, so (bit) would probably be too ambiguous. I do like the brevity of a 4-letter function, though. A lot of my lisp coding is genetic and probabilistic so it gets used a lot.
- galfarragem 7y agoGenuine questions that probably most here want to put but seem to be afraid of: Why Bel? What are the problems that Bel wants to solve? Is this an hobby project or something more serious?
- pmarin 7y agoThe kind of questions that don't make sense in a forum where 'Hacker' is in the title.
- galfarragem 7y agoI believe that when somebody makes a "Show HN" post, this person wants feedback. You can't give it without understanding the project.
- netcan 7y agoCritical questions have a tendency to be loaded, one way or another. Yours is (unintentionally, I assume) loaded with the assumption that projects are either hobby/toy projects or "serious" ones. The "ethos" OP alludes to is that this is a severely limiting fallacy and a criticism you should actively ignore.
- neonate 7y agohttps://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt?t=1570864329& https://sep.yimg.com/ty/cdn/paulgraham/bellanguage.txt?t=157... explains the purpose of the project. It's an attempt to axiomatize a complete programming language the way that McCarthy's Lisp did for computability. Sounds serious to me. Why can't it be both?
- netcan 7y agoI can't answer the main question, but my guess from pg's other work is that there is no dichotomy between hobby and serious. Frivolous seeming starting points can be powerful in unexplored ways. The www, most everything in it, and the stuff it's built out of are all rich with examples.
- repolfx 7y agoThere's a typecheck function in the standard library, but with no documentation in the Bel source anywhere it's hard to know what it does. For people like me who want static typing and a powerful type system to catch errors, does lisp have anything to offer? My understanding is that it predates decent type systems and lisps will always be genealogically much closer to Python than, say, a Haskell or even a Kotlin.
- ristos 7y agoYeah you can do optional static typing in common lisp: https://medium.com/@MartinCracauer/static-type-checking-in-the-programmable-programming-language-lisp-79bb79eb068a https://medium.com/@MartinCracauer/static-type-checking-in-t... The typing discipline in strong. I think it also has type inference but I'm not 100% sure
- pg 7y agoWhat this (def typecheck ((var f) arg env s r m) (mev (cons (list (list f (list 'quote arg)) env) (fu (s r m) (if (car r) (pass var arg env s (cdr r) m) (sigerr 'mistype s r m))) s) r m)) says is, first create a function call (list f (list 'quote arg)) in which the function describing the type (e.g. int) is called on the argument that came in for that parameter. Its value will end up on the return value stack, r. So in the next step you look at the first thing on the return value stack (car r) If it's true, you keep going as if the parameter had been a naked one, with no type restriction (pass var arg env s (cdr r) m) and if it's false, you signal an error (sigerr 'mistype s r m)
- alfiedotwtf 7y agoI remember reading pg's article on Lisp and startups, and at the time questioned if it was just mere luck. Then having a cursory look at Lisp, I questioned its relevance to the modern world. ... fast forward a decade later and I'm reading books on functional and logical languages for work. After the first chapter of The Little Schemer, I was at first blown away with the content, but then sad after I realised I had put off reading it late in my life. If you're reading this comment and thinking Lisp and what's the point? Take a deep dive. It you're still questioning why, I highly encourage you to read The Little Schemer (and then all the others in the series). Scheme, Lisp, and now Bel, are a super power... pg's article was spot on.
- chrismorgan 7y agoYou and I both like Rust. Concrete performance is one key reason why I choose to use Rust for various things, and all Lisps I know of are just generally slower and use more resources; I’m not aware of any Lisp attempting to address this problem, and from what I do understand of Lisps (though I’ve never seriously coded in one) they seem at least somewhat incompatible with such performance. I’m interested in whether you have any remarks on this apparent conflict of goals. (I’d love to be credibly told I’m completely wrong, because syntax aside, which I could get used to eventually, I rather like the model of Lisps and some of the features that supports.)
- capableweb 7y agoI don't think "Lisps are just generally slower and use more resources" is true. According to "TechEmpower Web Framework Benchmarks" (which might not be perfect but at least give some indication), Clojure is one of the fastest language (in terms of handling responses per second) for building a JSON API with. Take a look at https://metosin.github.io/reitit/performance.html https://metosin.github.io/reitit/performance.html
- StreamBright 7y agoThe fastest for these sort of things are usually C++, Rust, C projects[1]. The fastest Java projects are Rapidoid, wizzardo-http, and proteus. The link you provided does not have a comprehensive comparison of different HTTP JSON frameworks. 1. https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=json https://www.techempower.com/benchmarks/#section=data-r18&hw=...
- foobar_ 7y agoAlmost every language has macros now. Lisp is pointless.
- capableweb 7y agoDon't let the name "macro" fool you, Macros in Lisp is completely different than the macros you do in other languages. In other languages, you're basically just outputting source code. In Lisp, since the source code is actually the program, you can program the program. There is a good perspective from a Perl developer about Lisp macros here: http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.h...
- gus_massa 7y agoIn some languages, like C, you don't have the full power of main language inside the macros. In other languages, you have the whole language inside the macros, but the community and the docs discourage you about writing macros. As a related example, in rust the macros have a ! so it's easy to distinguish macros from function calls. In the lisp family of languages, the idea is that everyone can write macros. Macros are dangerous because they can do weird things, but functions can do weird things too. Functions are more restricted, but until you look at the source code you are not sure that they will not ignore all the arguments, or format your hard disk, or something weird in between. I know more about the internal working of racket. One of the open secrets is that it has a lot of macros that pretend to be function. They behave nicely like function, but under the hood they are macros, mostly to generate more efficient code in the common case. For example functions with keywords, of functions with contracts, or functions like `in-list` that can be used in a `for` to iterate a list. (Other macros are weird and do very complex things, in particular `for` and `match` are implemented as macros inside the language.)
- cousin_it 7y agoWhenever I see a new programming language, this list of questions by Frank Atanassow comes to mind: 1. What problem does this language solve? How can I make it precise? 2. How can I show it solves this problem? How can I make it precise? 3. Is there another solution? Do other languages solve this problem? How? What are the advantages of my solution? of their solution? What are the disadvantages of my solution? of their solution? 4. How can I show that my solution cannot be expressed in some other language? That is, what is the unique property of my language which is lacking in others which enables a solution? 5. What parts of my language are essential to that unique property? Do read the whole post (http://lambda-the-ultimate.org/node/687#comment-18074 http://lambda-the-ultimate.org/node/687#comment-18074), it has lots of elaboration on these questions. From a skim of the Bel materials, I couldn't answer these questions. Maybe PG or someone else can take a stab at the answer?
- capableweb 7y agoI think you're unable to answer those questions as the language does not seem to aim to try to offer any answer to those questions. Bel seems to be an experiment, and maybe once the "specification" phase has been done, some of those questions could be answered. Here is the relevant parts from the language document: > Bel is an attempt to answer the question: what happens if, instead of switching from the formal to the implementation phase as soon as possible, you try to delay that switch for as long as possible? If you keep using the axiomatic approach till you have something close to a complete programming language, what axioms do you need, and what does the resulting language look like? > I want to be clear about what Bel is and isn't. Although it has a lot more features than McCarthy's 1960 Lisp, it's still only the product of the formal phase. This is not a language you can use to program computers, just as the Lisp in the 1960 paper wasn't. Mainly because, like McCarthy's Lisp, it is not at all concerned with efficiency. When I define append in Bel, I'm saying what append means, not trying to provide an efficient implementation of it.
- rjyoungling 7y agoThat's fair, but I love PG so I'm biased lol
- 7y ago
- netcan 7y agoWelcome back pg. I hope it was a pleasant return.
- quickthrower2 7y agoSeems a bit closer to the lambda calculus than most lisps. Building stuff up from such primitive types.
- waterhouse 7y agoA couple of things on my checklist for mathematical purity are (a) first-class macros and (b) hardcoded builtins. It looks like Bel does have first-class macros. As for (b)... > Some atoms evaluate to themselves. All characters and streams do, along with the symbols nil, t, o, and apply. All other symbols are variable names The definitions of "ev" and "literal" establish that nil, t, o, and apply are in fact hardcoded and unchangeable. Did you consider having them be variables too, which just happen to be self-bound (or bound to distinctive objects)? nil is a bit of a special case because it's also the end of a list, and "(let nil 3 5)" implicitly ends with " . nil"; o might be an issue too (said Tom arguably); but apply and t seem like they could be plain variables. P.S. It looks like you did in fact implement a full numerical tower—complex numbers, made of two signed rational numbers, each made of a sign and a nonnegative rational number, each made of two nonnegative integers, each of which is a list of zero or more t's. Nicely done.
- deleted 7y ago[deleted]
- Zenst 7y agoShort direct intro, link to guide for language, here is a link to code examples. This is for me are the things I look for when reading about some new computer language release upon here or anywhere and this just wins upon that first impression. It's kinda like the early days of quality usenet posts nostalgia in the direct and to the point aspect, and I love that.
- dfranke 7y agoReproduced from feedback that I gave pg on an earlier draft (omitting things he seems to have addressed): When you say, > But I also believe it will be possible to write efficient implementations based on Bel, by adding restrictions. I'm having trouble picturing what such restrictions would look like. The difficulty here is that, although you speak of axioms, this is not really an axiomatic specification; it's an operational one, and you've provided primitives that permit a great deal of introspection into that operation. For example, you've defined closures as lists with a particular form, and from your definition of the basic operations on lists it follows that the programmer can introspect into them as such, even at runtime. You can't provide any implementation of closures more efficient than the one you've given without violating your spec, because doing so would change the result of calling car and cdr on closure objects. To change this would not be a mere matter of "adding restrictions"; it would be taking a sledgehammer to a substantial piece of your edifice and replacing it with something new. If closures were their own kind of object and had their own functions for introspection, then a restriction could be that those functions are unavailable at runtime and can be only be used from macros. But there's no sane way to restrict cdr. A true axiomatic specification would deliberately leave such internals undefined. Closures aren't necessarily lists, they're just values that can be applied to other values and behave the same as any other closure that's equivalent up to alpha, beta, and eta conversion. Natural numbers aren't necessarily lists, they're just values that obey the Peano axioms. The axioms are silent on what happens if you try to take the cdr of one, so that's left to the implementation to pick something that can be implemented efficiently. Another benefit of specifying things in this style is that you get much greater concision than any executable specification can possible give you, without any loss of rigor. Suppose you want to include matrix operations in your standard library. Instead of having to put an implementation of matrix inversion into your spec, you could just write that for all x, (or (not (is-square-matrix x)) (singular x) (= (* x (inv x)) (id-matrix (dim x)))) Which presuming you've already specified the constituent functions is every bit as rigorous as giving an implementation. And although you can't automate turning this into something executable (you can straightforwardly specify a halting oracle this way), you can automate turning this into an executable fuzz test that generates a bunch of random matrices and ensures that the specification holds. If you do stick with an operational spec, it would help to actually give a formal small-step semantics, because without a running implementation to try, some of the prose concerning the primitives and special forms leaves your intent unclear. I'm specifically puzzling over the `where` form, because you haven't explained what you mean by what pair a value comes from or why that pair or its location within it should be unique. What should (where '#1(#1 . #1)) evaluate to? Without understanding this I don't really understand the macro system.
- mark_l_watson 7y agoI like the syntax for function chaining: (dedup:sort < "abracadabra") I assume that dedup and sort are separate functions.
- shrubble 7y agoWill someone please teach pg some APL? It seems to be the missing piece of what he is working towards.
- dang 7y agoPlease say more. What would you bring from APL into Lisp?
- dkersten 7y agoIn another comment above, pg wrote: "language A is better than language B if programs are shorter in A" APL's terseness due to weird characters aside, since he did say that's not what he meant, APL can do A LOT by chaining a small count of operators together, which, to me, does seem to fit with the above quote rather well. I would personally also suggest a Forth-derivative like Factor as another language that would meet the criteria of being small in parse-tree terms (and incidentally also in tokens). As for what it would bring into Lisp.. I dunno. Maybe nothing :)
- shrubble 7y agoIf Lisp is meant to be a formal model of computation ( a quote from the Bel article by pg), then other formal models of computation should also be examined; perhaps 'compare and contrast' of two different perspectives will lead to a new thought or even a sort of amalgamation. Lisp and Bel's basic data structure is the list. APL's is the array, which can be seen as a list or in multidimensional form as a list of lists. Lisp uses a form of notation that is quite different from the APL notation. If there are advantages to both notations then it makes sense to study both of them. Bel's description of functions might benefit from looking at APL's niladic, monadic and dyadic functions, as another example.
- orthoxerox 7y agoWhy does apply evaluate to itself instead of (lit prim apply)?
- pg 7y agoBecause it's not a primitive. It's handled by a special case in the interpreter, (= f apply) (applyf (car args) (reduce join (cdr args)) a s r m) rather than being something whose behavior you have to assume.
- adreamingsoul 7y agoInstead of writing code on the weekend, I instead have been thinking about and visualizing the code that I would like to write. That way I can use my hands for other activities, like playing in the dirt.
- est31 7y agoThe source is hosted on the yahoo CDN. Interesting.
- tosh 7y agoI always wondered about the back story. I guess Yahoo Store & migrating away from Yahoo infrastructure? Who owns the domain now? pg?
- the_watcher 7y agoIt was built using Yahoo Stores, which is what Viaweb became when Yahoo purchased it. He just continues to use it.
- codr7 7y agoI just don't think yet another Lisp is going to do it, and I've written a few [0]. Lisp is fine for what it is, one extreme of the spectrum and a child of its time; but far from the final answer to anything. We would be better off triangulating new ideas than polishing our crufty icons. Lisp was a giant leap, hopefully not the last. [0] https://github.com/codr7/g-fu https://github.com/codr7/g-fu
- codingdave 7y ago> I just don't think yet another Lisp is going to do it Going to do what? I wasn't aware there was a specific goal that had to be met here?
- soulofmischief 7y agoHell, if we're talking about the next emergent layer of software, autonomous code / artificial intelligence, I'd say LISP has a better shot than most languages. Performance-critical code can still be refactored into C but LISP has much more built-in capability for advanced genetic coding and reflection.
- throw_xyzyz 7y agoC is pretty far away from the hardware these days. We are missing the true low level languages that C used to be in the 80s/90s.
- codr7 7y agoLisp had a shot since 1958, somewhere along the way it even made sense.
- codr7 7y agoChange anything, I thought that was obvious.
- braythwayt 7y agoIf someone picks up Bel and is changed by it, then something has been changed. YOUR problem is that you have an all-or-nothing perspective that change only matters if it is massive, global, change-at-scale. Change matters in the small. If building Bel changed nobody except PG for the better, then it is still change and it still matters. Just not to you. As a bonus—and this is a happy accident, not core to my point—sometimes change in the small unexpectedly leads to change in the large. See microcomputers, web browsers, and so many other things scoffed at as things that simply could never displace the incumbent technologies.
- Geee 7y agopaulgraham.com isn't secured by HTTPS. The reason why sites like this should be secured is content manipulation attacks. Now I can't trust that the Bel source code that I see is actually written by pg.
- segmondy 7y agoHttps doesn’t guarantee that. Someone could manipulate the content on the host.
- segmondy 7y agoVery nice for the depth and quality. This could pass for a very good grad school project. Pg, how much effort did it take to figure out the axiomatic approach for previous formal methods. How long and how much effort did it take to produce this?
- jxub 7y agoHyped to have you back in here pg :)
- vessenes 7y agoPaul, this is really nice - I’m glad to see you doing some research about stuff you clearly love. Other than because you want to, do you have any sort of longer form apology for bel worked out that you want to share? I ask because I’m curious how you’re thinking about play, work and legacy at this point in your career.
- pg 7y agoI talk about this in the first section of the The Bel Language: http://paulgraham.com/lib/paulgraham/bellanguage.txt http://paulgraham.com/lib/paulgraham/bellanguage.txt
- vessenes 7y agoI did read that before I asked, I promise :) I was curious more about how you think about your own time at this phase in your career -- are you mostly 'playing'? Is this "serious play"? Is it motivated by anything beyond personal interest? I ask because I'm monitoring my own projects and time commitments more seriously as I hit my mid 40s and trying to make sense of how and when I've had the best impact, globally, personally, to my own happiness, etc. One of the keys for me seems to have been to pay attention to what interests/intrigues me, and I'm curious what your experience is on that front as well -- you have a pretty unique amount of experience assessing and watching companies that have in some cases made a major amount of change in the world. Anyway, I guess I'm just asking for a sort of 'mid career thoughts' essay from you, or at least wondering if you're thinking much about it.
- pg 7y agoThis was something I'd meant to do for a long time, and wanting to work on it was one of the reasons I retired from YC. Being overtly ambitious would have provoked haters, but few will see this thread now, so I'll tell you: the goal was to discover the Platonic form of Lisp, which is something I could always sense lurking beneath the surface of the many dialects I've used, but hidden by mistaken design choices. (T was probably the best in this respect.) I don't know how much my experience translates to other people, because my "career" has been unusually random, but when I retired from YC what I was thinking was that at 49, if there was something I'd been meaning to do, I'd better do it.
- TekMol 7y agoBel has four fundamental data types: symbols, pairs, characters, and streams. No numbers? Then a bit further down it says: (+ 1 2) returns 3 Now suddenly there are numbers. What am I missing?
- sillysaurusx 7y agoIt’s best not to get hung up on formality. Lisp (and expecially arc) are powerful due to what they can do, not due to what they define. Racket might disagree with that though. From a prototyping perspective it would be a waste of time and overly constraining to define what numbers are or what you can do with them. That’s best left to the implementation. I can hear everyone groaning in unison with that, but trust me. Nowadays every implementation will choose some sensible default for numbers. If you transpile bel to JS, you get JS’s defaults. Ditto for Lua. But crucially, algorithms written for one generally work for the other.
- krapp 7y agoBut Bel obviously has a numeric type if arithmetic works...
- deleted 7y ago[deleted]
- sillysaurusx 7y agoSure, but all languages do. In any case, I was mistaken. Numbers are defined.
- pjscott 7y agoNumbers are defined further down, in terms of those primitives. Search for the phrase "Now we come to the code that implements numbers."
- pg 7y agoNumbers are represented using pairs. Specifically (lit num (sign n d) (sign n d)) where the first (sign n d) is the real component and the second the imaginary component. A sign is either + or -, and n and d are unary integers (i.e. lists of t) representing a numerator and denominator.
- iamwil 7y agoAs for the name, I figured it has a couple connotations. AT&T's Bell labs. Belle is French for Beautiful Bel is the 7th ASCII character and it use to ring an electro mechanical bell in computers, before they had speakers or sound cards. B is the second letter after A, with which Arc, his first Lisp variant was named. And both have three letters.
- stevelosh 7y ago> For example the bell character, after which Bel is named, is \bel
- machawinka 7y agoWonder why `no` instead of `not`.
- pg 7y agoBecause falsity is also the empty list.
- 1penny42cents 7y ago@pg: hyperlinks aren't visible on mobile web
- georgeEsb 7y agoBeing so simple reminds me of RISC
- vincent-toups 7y agoSeems goofy, but ok. I'll just use Scheme.
- brudgers 7y agoI've only read the first twenty pages approximately. I'd like to see a little more disentangling of characters and strings as inputs to automata from text as something people read. The narrow technical meaning is implied in the text, but the use of "string" as a synonym for "text" is common enough that it might be worth being a little more explicit or didactic or pedantic or whatever. The second thought is that lists smell like a type of stream. Successive calls to `next` on `rest` don't necessarily discern between lists and streams. The difference seems to be a compile time assertion that a list is a finite stream. Or in other words, a sufficiently long list is indistinguishable from an infinite stream (or generator). I'm not sure you can have a lisp without lists, but they seem more like objects of type stream that are particularly useful when representing computer programs than a fundamental type. Whether there are really two fundamental types of sequences, depends on how platonic really really is. All with the caveat, that I'm not smart enough to know if the halting problem makes a terminating type fundamental.
- SkyMarshal 7y ago>Bel is an attempt to answer the question: what happens if, instead of switching from the formal to the implementation phase as soon as possible, you try to delay that switch for as long as possible? If you keep using the axiomatic approach till you have something close to a complete programming language, what axioms do you need, and what does the resulting language look like? I really like this approach and have wondered in recent years what a programming language designed with this approach would look like. There are a few that come close, probably including Haskell and some of the more obscure functional languages and theorem prover languages. Will be really interesting to see a Lisp developed under this objective. >But I also believe that it will be possible to write efficient implementations based on Bel, by adding restrictions. If you want a language with expressive power, clarity, and efficiency, it may work better to start with expressive power and clarity, and then add restrictions, than to approach from another direction. I also think this notion of restrictions, or constraint-driven development (CDD), is an important concept. PG outlines two types of restrictions above. The first is simply choosing power and clarity over efficiency in the formative stages of the language and all the tradeoffs that go with that. The second is adding additional restrictions later once it's more clear how the language should be structured and should function, and then restricting some of that functionality in order to achieve efficiency. Reminds of the essay "Out of the Tarpit" [1] and controlling complexity in software systems. I believe a constraints-based approach at the language level is one of the most effective ways of managing software complexity. [1]:https://github.com/papers-we-love/papers-we-love/blob/master/design/out-of-the-tar-pit.pdf https://github.com/papers-we-love/papers-we-love/blob/master...
- drcode 7y agoI think at the end of the day, the question is whether a compiler for this type of language could efficiently handle a function like distinct-sorted: > (distinct-sorted '(foo bar foo baz)) (bar baz foo) This is a function that usually requires efficient hash tables and arrays to be performant, a hash table for detecting the duplicates, an array for efficient sorting. However, both the hash map and array could theoretically be "optimized away", since they are not exposed as part of the output. A language like Bel that does not have native hash maps or arrays and instead uses association lists would have to rely entirely on the compiler to find and perform these optimizations to be considered a usable tool.
- sooheon 7y agoInteresting example of a unit test of sorts for language usability. Got any others?
- drcode 7y agoI'm no language expert, but the there things I can think of that make bel impractical without major compiler trickery are (1) lack of primitive hash tables (2) lack of primitive arrays (3) no support for tail call optimization (though that third thing is probably fixable with the right compiler tricks) The other concern I have is the lack of a literal associative data structure syntax (like curly braces in clojure) It seems that would negatively impact pg's goal of "code simplicity" quite a bit.
- arundelo 7y ago(1) lack of primitive hash tables (2) lack of primitive arrays I'll note that if there are primitive arrays and the compiler optimizes arithmetic, the rest of the hash table can be implemented in Bel. Also, maybe a Sufficiently Smart Compiler could prove that a list's cdrs will never change, store it in cdr-coded form, and treat it like an array (with the ability to zoom right to, say, element 74087 without chasing a bunch of pointers).
- stereolambda 7y agoI like the (English) syntax of the article. It seems to have the same concise feeling as the language itself. I like to think that's why pg chooses falsity over falsehood. It's a little strange to have (id 'a) return nil. Also having car and cdr as historical holdouts when most of the naming seems to aim at an ahistorical stylistic. Not very deep remarks, since I would need more time to digest.
- QueensGambit 7y agoThis seems like a DSL masking itself as a programming language. Will this axiomatic approach allow declaration of domain specific operators like credit/debit? Is this is an attempt to make application development axiomatic?
- pwpwp 7y agoNo fexprs? https://web.cs.wpi.edu/~jshutt/kernel.html https://web.cs.wpi.edu/~jshutt/kernel.html
- fao_ 7y ago> (dedup:sort < "abracadabra") "abcdr" I extremely like this format. I think clojure has something similar?
- wintorez 7y agoI have a hunch that this is going to become a big deal in the future. Not sure why.
- juskrey 7y agoHave you considered posting this on HN under some pseudonym (including original website etc) to make experiment more .. interesting?
- ericd 7y agoI haven't had a chance to dig in yet, just wanted to say congrats on getting it out into the world!
- excessive 7y agoThis one seems backwards to me: (2 '(a b c)) In addition to being data structures, I like to think of lists/arrays as functions which map integers to the contents. This nicely generalizes to hash tables / associative arrays, and then further to actual functions. If that's all reasonable, then ('(a b c) 2) is the right order for application. However, maybe pg is just thinking of 2 as a shorthand for cadr or similar.
- andreareina 7y agoIt seems to be borrowing from clojure, in which both (field container) and (container field) do the same thing.
- pg 7y agoInitially I would have preferred that. I did it that way in Arc. But since functions are lists in Bel, I couldn't do that, or you wouldn't be able to call a function on a number. As often happened with things I was forced into, though, I not only got used to putting numbers first but started to prefer it. It means for example you can compose them with other callable things.
- e12e 7y agoAm I reading that right, that: (2 '(a b c)) Is equivalent to: (second '(a b c)) And that would work for strings as well: (5 "Hello, world!") > "o" Which in turn means 'car and' 1 are equivalent? (probably means 'car should be thrown out, because surely '1 is clearer? Ed: and with some notation to differenciate "element at N" and "tail behind N" you could get even more mileage out of integers? And then to generalize to lists of lists to reference elements and sub-sections (sub dimensions, like cubes) of matrices? Not sure what would be nice, perhaps star or ellipsis? (1... '(a b c)) >'(b c) ('(1..) '(0..2) '( (a b c) (d e f)) >'( (b c) (d f)) Or something?
- pg 7y agoIt would not be clearer to use 1 instead of car when you were using a pair to represent a tree, rather than a list, and you were traversing the left and right branches using car and cdr.
- idm 7y agoHi Paul - looks interesting! What is the license? My presumption is that you intentionally did not embed a license within either of the documents.
- zahreeley 7y agoLooks garbage
- alexkcd 7y agoI really like how type checking is implemented for parameter lists. I think there's a more generalized extension of this. Specifically, I think that there exists a lisp with a set of axioms that split program execution into "compile-time" execution (facts known about the program that are invariant to input) and a second "runtime" execution pass (facts that depend on dynamic input). For example, multiplying a 2d array that's defined to be MxN by an array that's defined to be NxO should yield a type that's known to be MxO (even if the values of the array are not yet known). Or if the first parameter is known to be an upper-triangular matrix, then we can optimize the multiplication operation by culling the multiplication AST at "compile-time". This compile-time optimized AST could then be lowered to machine code and executed by inputting "runtime" known facts. I think that this is what's needed to create the most optimally efficient "compiled" language. Type systems in e.g. Haskell and Rust help with optimization when spitting out machine code, but they're often incomplete (e.g., we know more at compile time than what's often captured in the type system). I've put "compilation" in quotes, because compilation here just means program execution with run-time invariant values in order to build an AST that can then be executed with run-time dependent values. Is anyone aware of a language that takes this approach?
- jimbo1qaz 7y agohttps://github.com/idris-lang/Idris-dev/blob/5965fb16210b18444bc0435286d4bcd4f0e260a4/libs/contrib/Data/Matrix/Algebraic.idr#L85 https://github.com/idris-lang/Idris-dev/blob/5965fb16210b184... Idris is not a Lisp and I've never used it, but it has dependent types (types incorporating values) and encodes matrix dimensions into the type system (I think only matrix multiplications which can be proven to have matching dimensions can compile). I think the dimension parameters are erased, and generic at runtime (whereas C++ template int parameters are hard-coded at compile time). IDK if it uses dependent types for optimization.
- e12e 7y agoI'm not sure, but this seems a bit like how Julia specialize functions based on type of arguments? Or maybe it's the inverse - as Julia creates specialized functions for you (eg add can take numbers, but will be specialized for both int32 and int64 and execute via appropriate machine instructions). In fact, I think Julia is a great example of taking some good parts of scheme and building a more conventional (in terms of syntax anyway) language on top.
- Liron 7y agoHow'd you pick the name?
- gdubs 7y agoAside: Nice to see you hear again, pg.
- kizer 7y agoO GLORY DAY OUR PAUL HATH RETURNED! Also is Lisp just syntactic sugar over Lambda calculus? All the Lisp people (I.e., the authors of books I’ve skimmed on lisp) worship it, but it’s simply an encoding of a n-ary tree, no? I know you can do elegant things like define lisp in lisp and the whole homoiconicity[?] thing - but don’t these endless opportunities stem from n-ary trees? My point is that of course Lisp can do this and that if it’s simply a representation of a tree - trees capture as models like all the structures of information.
- e12e 7y agoSo, how does one bootstrap the interpreter? Is it available as a Racket "language" or is it compatible with most/some lisps/schemes?
- kingofpee 7y agoI'm shocked it's the first post of Paul since 2014 I feel lucky now to be online ;)
- varjag 7y agoIs 'sys' really necessary, when you already have streams?
- machawinka 7y agoThere is not mention of licensing anywhere. Is it freely distributable/modifiable?
- yellowapple 7y agoAt the risk of some bikeshedding: The name "car" is McCarthy's. It's a reference to the architecture of the first computer Lisp ran on. But though the name is a historical accident, it works so well in practice that there's no reason to change it. While I understand the rationale here, would this not have been a good opportunity to encourage something a bit less vestigial than "car" and "cdr"? Say, "head" and "tail"? Or "left" and "right"? A lot of things come to mind when seeing a bunch of cars and cdrs and such everywhere in Lisp code, and "works so well in practice" ain't exactly one of them, IMO.
- pg 7y agoAs names, car and cdr are great: short, and just the right visual distance apart. The only argument against them is that they're not mnemonic. But (a) more mnemonic names tend to be over-specific (not all cdrs are tails), and (b) after a week of using Lisp, car and cdr mean the two halves of a cons cell, and languages should be designed for people who've used them for more than a week.
- yellowapple 7y ago> more mnemonic names tend to be over-specific I feel like this applies just as much (if not more so) to calling something the "contents of the address part of the register" or "contents of the decrement part of the register", especially when in actuality the "car" and "cdr" of a cons cell are implemented in a way that has nothing to do with an IBM 704. > short, and just the right visual distance apart Even shorter (and similar visual distance apart) would be cl and cr (for "cons left" and "cons right", i.e. the car and cdr, respectively). Or pl and pr if we swap "cons"/"cell" for "pair". Like car and cdr, these can be combined into other operations, like (cllllr foo) -> (cl (cl (cl (cl (cr foo))))). Heck, we could go even shorter with just "l" and "r". They're even kinda pronounceable ("cull", "curr", "cullullullullurr"). Literally all the upsides of "car" and "cdr" without any historical baggage. Point being, if Bel is supposed to be a reconceptualization of Lisp, it feels really weird to not reconceptualize how we talk about cons cells and the contents thereof. > after a week of using Lisp, car and cdr mean the two halves of a cons cell, This could be true for any chosen terminology here. Unless you meant Lisp in general and not this particular dialect, in which case there are counterexamples to that (namely: Clojure, last I checked).
- robobro 7y agoHow do I install this?
- z3phyr 7y agoI can't find the definition of id in bel.bel file. Did I miss it? @pg
- eggsyntax 7y agoThere are two things I found confusing in the first part of the guide (ie the part up to "Reading the Source"). The first is 'where', which is addressed in another thread on this page. The second is this: This is a proper list: (a b c) and this is not: (a b . c) Could someone clarify how to interpret '(a b . c)'? How would it be represented in the non-abbreviated dot notation for pairs? It's not '(a . (b . (c . nil))' -- is it '((a . b) . c)'? The only Lisp I'm fluent in is Clojure, so I'm not used to the dot notation; otherwise this might be obvious.