[HN Gopher] XL: An Extensible Programming Language
___________________________________________________________________
XL: An Extensible Programming Language
Author : PaulHoule
Score : 139 points
Date : 2024-02-21 12:39 UTC (10 hours ago)
(HTM) web link (xlr.sourceforge.io)
(TXT) w3m dump (xlr.sourceforge.io)
| tempodox wrote:
| This seems to be Prolog with a large dose of syntactic sugar.
| bradrn wrote:
| More Lisp than Prolog... I don't see any constraint-solving
| here, just macros.
| mapcars wrote:
| I don't see them as macros either, it's more like pattern
| matching and replacing patterns with expressions. Maybe there
| is a term for that?
|
| And it's not compile-time only, I'm pretty sure you can't do
| this as a macro:
|
| >loop Body is { Body; loop Body }
| bradrn wrote:
| > it's more like pattern matching and replacing patterns
| with expressions
|
| Scheme macros use pattern-matching.
|
| > loop Body is { Body; loop Body }
|
| This, though, is definitely strange. I'm not quite sure how
| it works.
| c3d wrote:
| You can do exactly that, and this is how this is defined
| in the built-in library
|
| https://github.com/c3d/xl/blob/fast/src/builtins.xl#L222
|
| How it works is what I tried to document in the document
| above. The trick is to have some fixed semantics on how
| rewrites are done, but a lot of freedom in how this is
| implemented. And this is far from perfect ATM.
|
| For example, if you write "X is 2", this can be
| implemented as a constant, as a function returning a
| constant, or as a macro. However, if you write "X is
| seconds" in Tao3D, where "seconds" returns the current
| number of seconds in the clock, then it can no longer be
| a constant value. You still can use macro replacement (or
| inlining) or turn it into a function.
|
| More details here: https://xlr.sourceforge.io/#compiling-
| xl
| c3d wrote:
| There is no backtracking, but being able to implement Prolog on
| an XL basis was an important part of the original design of the
| "runtime" version of XL.
| netbioserror wrote:
| Seems cool. But I'm not convinced extensible languages benefit
| from adding a variety of syntactic forms. As your ability to
| extend the feature-set increases, the need for a single regular
| syntactic form increases. Lisp may not be _appealing_ to
| beginners because of its parenthesis, but they absolutely are
| what makes it work so well for its intended use cases.
|
| Really, all use cases. I'm actually a fan of the parenthesis.
| Lisp feels like aesthetic perfection to me. Languages like
| Haskell and XL here just look like line noise to my brain.
| mapcars wrote:
| There are lisps without parens too, it's not strictly required
| for parsing and evaluation. I think the main purpose of parens
| is to highlight the syntax tree for developer manipulations
| with macros
| diggan wrote:
| > There are lisps without parens too
|
| Are there any that come close to the usage of lisps with
| proper s-expressions? I've seen them come and go, but no
| "lisp without parens" that seem to stick around for longer
| period. I guess that should say something? Maybe we just
| haven't found the right way of exposing it though.
|
| Personally, when I've given it a try, the indentation-based
| syntax always makes it hard to use without faults. Maybe it's
| just a "getting used to" thing, but it seems like a mistake
| to depend on invisible characters for syntax.
|
| FWIW, I hardly ever write macros (mostly use Clojure/Script),
| so not sure the main purpose of the parens is macro writing
| for me. S-expressions with something like parinfer just makes
| programming a lot more enjoyable and easy, especially
| compared to all the C-syntax-like languages.
| tehologist wrote:
| I am pretty sure logo is mostly a lisp without parenthesis.
| I find it a lot more readable than most lisp dialects. I am
| not sure why it never caught on.
| runlaszlorun wrote:
| I was about to post exactly the same... haha.
|
| I've been doing a recent deep dive in languages as part
| of my own overly ambitious language attempt and only
| recently found out that Logo was in fact Lisp based.
|
| I'm guessing that the reason it might not have taken off
| is because, unfortunately, it was looked upon as a 'kid
| language'.
|
| The goals of Papert and others seem a far cry from where
| tech has landed today.
|
| edit: for an egregious typo
| mbork_pl wrote:
| It is. A piece of trivia: AFAIR, you say
| SUM 2 3
|
| in Logo to add two numbers, but [SUM 2 3
| 4]
|
| to add more. (Though I learned Logo more than three
| decades ago, so I might be mistaken.)
| samatman wrote:
| > _Are there any that come close to the usage of lisps with
| proper s-expressions?_
|
| If you consider Julia a Lisp, which I would argue you
| should, it may be the most widely-used Lisp currently. The
| only way you'll see an s-expression is is to call
| Meta.show_sexpr.
|
| If you consider Dylan a Lisp, you should consider Julia a
| Lisp as well. If you don't consider Dylan a Lisp, I have to
| conclude that you consider the s-expressions to be part of
| the definition of a Lisp. Which isn't an unreasonable
| taxonomy, but isn't the one I use.
| slooonz wrote:
| IMO, there's a wide unexplored design space between the
| minimalism of Lisp and richness of other languages. A
| programming language inspired by something like KDL
| (https://github.com/kdl-org/kdl) has the potential to be in a
| very sweet spot between the two. "Everything is a node" instead
| of "everything is a list" is only slightly more complicated,
| but also vastly more readable that a soup of parenthesis.
| mbork_pl wrote:
| Where would you put Lua on this spectrum?
|
| Also, I do not find Lisp unreadable - you train your brain to
| ignore the parens and look at the indentation instead pretty
| quickly. And you can always tell Emacs to gray out the parens
| if you really want. ;-)
| slooonz wrote:
| > you train your brain to ignore the parens and look at the
| indentation instead pretty quickly
|
| But I don't want to train my brain to ignore useless
| syntactic noise, I want my brain to be guided by helpful
| syntactic guides.
| agumonkey wrote:
| you heard of rhombus ?
|
| https://old.reddit.com/r/lisp/comments/1aw7jim/rhombus_a_new.
| ..
| shiandow wrote:
| I'm starting to be increasingly certain that making a new
| (sub)language to express and solve your problems is the highest
| form of programming.
|
| You'd think the ability to define custom syntax would be the
| most important, but paradoxically lisp makes it a lot easier
| simply because there is _no_ syntax.
| netbioserror wrote:
| Exactly this. In addition, I've found that in almost all
| Lisps, macros are a niche feature that are not needed to
| solve many problems; however, because the actual invocation
| of macros and normal functions is the same S-expression form,
| almost all Lisp programs end up as some sort of DSL.
| Especially when you have arbitrary heterogeneous data
| structures like Clojure.
|
| Instead of dealing with chains of single assignments as in
| older C-like languages, you've got a bunch of compact calls
| fully in-context.
| fiddlerwoaroof wrote:
| So, "there is no syntax" is one of those things that isn't
| really true of most lisps: it's more true to say they have
| programmable syntax and the default syntax is minimal.
| runlaszlorun wrote:
| > Lisp may not be appealing to beginners because of its
| parenthesis
|
| You may have been referring to Lisp beginners, as opposed to
| overall programming beginners, but I've heard anecdotally that
| overall programming beginners take to Lisp better than those
| with experience in Algol style languages.
|
| I could see that. And will prob be testung that hypothesis out
| soon.
|
| And I too have become a fan of the parentheses.
| netbioserror wrote:
| I've always been curious about teaching total beginners Lisp.
| If the adage is true that learning a variety of languages
| will round you out in the long run, then experimenting with
| the S-expression, functional-lite model of Lisps as a first
| exposure should be low or zero-cost.
|
| And then we get to observe: If instead of modeling
| instructions and memory semantics, we first teach someone to
| model abstractions and computations, how do they think about
| programming differently even when eventually exposed to C and
| its lineage?
| cb321 wrote:
| Though the pool of students was biased towards those who
| excelled in high school which post 1980..1990 probably
| means _some_ prior exposure (i.e., not your "total
| beginners"), this was a big part of the original idea
| behind SICP-6.001 at MIT. AFAIK, they gave up on that
| experiment 15 years ago and moved to Python: http://lambda-
| the-ultimate.org/node/3312
|
| Being faculty / wordy, there is probably much written about
| it attempting to draw conclusions. There were definitely
| _some_ "smart, but total beginner programmers" in the mix,
| although I don't know how scientifically separated the
| performance of the "two 'some's" might have been.
| trws wrote:
| This is a bit anecdotal, but my freshman high school
| programming course, in 1999, was taught in Dr Scheme. I had
| already been programming in Q Basic and C++ at that point,
| and found it _maddening_. Not because of the perens really,
| editor was fine, but because of the lack of structured
| constructs for control flow that I was used to. Tail
| recursion, while now quite natural to me, just did not make
| sense at the time. My classmates had less trouble getting
| that bit because they had no preconceived notion of how
| control flow worked I think, and also didn't expect parts of
| the language to exist that either didn't or were hidden in
| the teaching mode we had to use it in. For most of a decade I
| listed that as my least favorite language of all time, until
| going back to find out that many of the things that were
| missing were actually there, they had just been hidden from
| us, pretty sure by imposing the "beginning student" mode:
| https://docs.racket-lang.org/drracket/htdp-langs.html
|
| Simplifying for teaching is good. Making useful things
| completely unavailable... not sure I agree.
| wubrr wrote:
| Agree about Haskell... as far as I'm aware there is actually no
| declarative/easily-readable definition of the Haskell syntax
| that is also complete, especially when it comes to the
| indentation rules, and the syntax is basically defined by the
| very (ironically) imperatively-defined GHC parser[0].
|
| I prefer a syntax like in Pure[1], where the ambiguous, hard to
| parse indentation-based syntax is replaced by explicit
| semicolons (Yeah, you can use braces/semicolons in Haskell as
| well, but most code doesn't).
|
| [0]
| https://github.com/ghc/ghc/blob/master/compiler/GHC/Parser/L...
|
| [1] https://agraef.github.io/pure-lang/
| Arelius wrote:
| Just wanted to say, thanks for the link to pure... I've been
| thinking a lot recently about languages based on term
| rewriting and hadn't seen it somehow.
| throwaway17_17 wrote:
| I would really like to see more discussions about the
| difficulties using LLVM can create for smaller language projects.
| The entire PL ecosystem is hyped up to revolve around the
| project, but rarely do you see language designers and solo/small
| group devs talk specifically about problems relying on LLVM. The
| history section of XL's page cites non-commitment to code
| compatibility between releases as their big struggle, which is a
| change from the more common complaints of inherent complexity and
| compilation time. I'd love to see more discussion of this, and
| maybe, see a focus on smaller backends and code generation tools
| for compilation, like QBE.
|
| Anyone with recommendations for reading would be welcome to dump
| those here.
| c3d wrote:
| I specifically addressed some of these topics in this talk:
| https://www.youtube.com/watch?v=Xzo7GIoDgAo
| Arelius wrote:
| For sure this.
|
| I have a little compiler from 10+ years ago I was working on.
| And I recall after I had put it down, and tried picking it back
| up just maybe a year later(?) The interfaces I was using in
| llvm all changed. It really took the wind out of my sails for
| jumping back in.
| c3d wrote:
| I realized I forgot to share my most memorable piece of code
| ever: llvm-crap (Compatibility Restoration Adaptive Protocol)
|
| https://github.com/c3d/xl/blob/master/src/llvm-crap.h
| c3d wrote:
| The really ugly stuff is here:
| https://github.com/c3d/xl/blob/master/src/llvm-crap.cpp
| sixthDot wrote:
| From what I can read the author got really unlucky with some
| kind of radical API changes. Maybe at that time the LLVM team
| was a bit less serious with deprecations ?
|
| I use LLVM since v9, nowadays I'm stuck on v15 (that's not
| because of LLVM btw).
|
| Between the two versions there's been a radical change too, i.e
| "opaque pointers", but the transition was rather smooth as we
| were provided, for a long time, the two versions of the
| functions affected by the change. Maybe the LLVM team got more
| serious since the author experienced the said difficulties ?
|
| Other thing I note is that the author uses the CPP API. I use
| the C one which exposes only a high-level subset of the CPP
| one. This encourages a saner use of LLVM, a more concrete
| separation between the front-end and the mid-end, although
| sometimes there are limitations.
|
| A simple example of what encourages the C API, especially since
| opaque ptrs are added, is not to rely on LLVM to retrieve the
| IR type of an IR value. That should always be done using the
| AST, eg with an `.ir` field in your nodes.
|
| Another one I remark, after a brief overview of LLVM-CRAP, is
| that the author had to change the internal data structure used,
| depending on the LLVM version [0]. Using the C API that would
| never had happened. The C API essentially allows to create
| block refs, instructions refs, value refs, type refs, contexts.
| Then you choose the containers you want to use to hold them. No
| need to switch to another stdcpp one, even if internally LLVM
| does so.
|
| [0]: https://github.com/c3d/xl/blob/master/src/llvm-
| crap.cpp#L265
| nurettin wrote:
| Following the "is" operator sections, I half expected it to build
| up to prolog facts, and then solve the zebra puzzle.
| cb321 wrote:
| Those interested in XL may also find the much older GalaxC by
| John Beetem interesting:
| https://community.element14.com/technologies/fpga-group/b/bl...
| c3d wrote:
| Why do you think it's older? XL started as LX around 1993, and
| IIRC self-compiled in 2004 or so.
| cb321 wrote:
| I am looking at a 1989 paper by Beetem & Beetem [1] but then
| it was called Galaxy.. I agree "much older" might be a bit..
| much. Haha.
|
| EDIT: Joking aside, I would love to hear a compare & contrast
| between Galaxy/GalaxC & LX/XL, though!!
|
| EDIT2: and via that first link, I think you can get to a full
| source code distribution compile-able with C on 32-bit Linux.
| Might have its own woes like LLVM hosting, but those might
| also be more solvable as part of a 64-bit port.
|
| [1] https://ieeexplore.ieee.org/abstract/document/28124/
| thechao wrote:
| I'd like C, but where I could use some syntax like:
| typedef _Load("libvector.so")(int) vector_int;
|
| to add arbitrary "builtin" types to the language. The idea being
| that "libvector.so" would use some spec-defined API to extend the
| core C language with the new features. This would replace a slew
| of features in the core C++ language (templates, classes, any
| sort of reflection, etc.), with some sort of 3rd party dylib you
| load. The idea is to keep the core language simple in the sense
| that it doesn't contain its own extension mechanism as syntax.
|
| I think my only worries would be how to handle life-time
| analysis, i.e., the moral equivalent of destructors, copy
| constructors, move-semantics, etc; maybe the dylib
| ('libvector.so', in this case) has to register stack-clean-up,
| copying, and move-semantics code-generation for the compiler?
| djha-skin wrote:
| Obligatory "lisp has had this for ages".
|
| Herein, macros seem to be invented from first principles, having
| only been exposed to imperative languages like C++. It is
| interesting to see macros here invented in the context of a
| language that is not homoiconic. I wonder how it stacks up
| against Rust macros.
| bradrn wrote:
| He claims it is homoiconic, though:
| https://xlr.sourceforge.io/#homoiconic-representation-of-pro...
| simplify wrote:
| "What is homoiconicity then? Typical definitions state that
| it is simply "code as data", will point to a relationship
| between a program's structure and syntax or note that the
| program source is expressed in a primitive data-type of the
| language. In the below, we will show that none of these
| definitions make much sense."
|
| https://www.expressionsofchange.org/dont-say-homoiconic/
| lebuffon wrote:
| Obligatory "FORTH has had this for ages". :-)
| runlaszlorun wrote:
| Is Forth really homoiconic? I'm asking as a recent fan of
| Forth. I would've thought to describe it as having strong,
| interactive metaprogramming but not necessarily homoiconic.
| Unless 'code = data, data = code' because they're all
| bytes... haha.
|
| Postscript would count as homoiconic, I'd think. Though I
| haven't actually seen programs that so this.
| c3d wrote:
| See the code around here to answer that question:
|
| Definition of 'if' statement:
| https://github.com/c3d/xl/blob/fast/src/builtins.xl#L155
| // If-then-else statement if [[true]] then True else
| False is True if [[false]] then True else False is
| False if [[true]] then True is True
| if [[false]] then True is false
|
| Definition of loops
| (https://github.com/c3d/xl/blob/fast/src/builtins.xl#L222)
| // Loops while Condition loop Body is if
| Condition then Body while Condition
| loop Body until Condition loop Body is {
| while not Condition loop Body } loop Body
| is { Body; loop Body } for Var in Low..High loop Body is
| Var := Low while Var < High loop Body
| Var := Var + 1
| DonHopkins wrote:
| What does "is is is" mean in this language?
|
| Maybe it's a quine?
|
| Can you define an "isn't" operator?
| runlaszlorun wrote:
| "is is is" would be called BillClintonLang, no?
| fuzztester wrote:
| Or TrumpLang.
|
| "It is what it is".
|
| https://www.google.com/search?q=Trump+it+is+what+it+is
|
| 2nd hit onwards.
| c3d wrote:
| Let's ask the interpreter / compiler: ./xl
| -nobuiltins -parse /tmp/glop.xl -style debug -show (infix
| is is is )
|
| So what it sees is a definition of a name 'is' as itself.
|
| Now, that name is very unlikely to be usable because `is` as an
| infix is so central to everything. As a matter of fact, it
| looks like even "is is 2" actually crashes the current
| implementation.
|
| Oh well. I wonder what a sensible error message on this would
| be. Probably: "Bill Clinton denied to comment on the meaning of
| that statement".
| maxpert wrote:
| Maybe a good DSL language. But I will avoid adding such
| complexity to my daily programming language at all costs.
| dkjaudyeqooe wrote:
| I've been working on something centered around extensibility, or
| metaprogramming, coming from a strictly imperative angle, with
| the belief that anything else (functional, relational/logic
| based, whatever) can be built on top of that.
|
| A few guiding principles are:
|
| - simplicity above all, with as few fundamental elements as
| possible
|
| - the parser is a separate issue, just write your own syntax to
| avoid the most divisive bikeshed element of PL design, or pick
| the C like or ALGOL like one out of the box. You very likely want
| your own syntax anyway as you write extensions.
|
| - every language element, from modules down to function calls,
| are first class, ie have an (implementing) type, can be stored in
| variables and used in expressions, be introspected and
| evaluated/deployed.
|
| - runs at compile time, compiles at run time (code
| generation/partial evaluation/dynamic code)
|
| - generates C, Java, Python and various bytecodes to maximise
| interoperability, code availability and deployability
|
| - has no standard runtime or standard library of its own, is
| entirely parasitic on other environments
|
| Even if it ends up being completely useless, it's a really
| interesting exercise in design.
| runlaszlorun wrote:
| Quite an ambitious offering by the author. Kudos to him/her.
|
| I have my own little (overly) ambitious language effort in a
| different direction and tend to beat myself up a bit since I feel
| like I should have more to show after almost 4 years.
|
| Then I noticed in the author's history section towards the end
| that they'd been working on this sine the early 90's and felt
| better about that.
| runlaszlorun wrote:
| Other than here, are there any other places online where folks
| writing their own languages tend to congregate?
|
| Having recently joined that tribe, I think it does take a
| particular worldview and type to be willing to undertake that. I
| suppose folks writing an OS perhaps even more so.
| dmux wrote:
| http://lambda-the-ultimate.org/ is one of the only PL-centric
| websites with discussion I can think of.
| throwaway87651 wrote:
| https://old.reddit.com/r/ProgrammingLanguages/
|
| For fun: https://esolangs.org/wiki/Main_Page
| c3d wrote:
| Author of the project here... Weird to see this generates such a
| discussion when the project is something like 20 years old, and
| has been quasi-dead for a while now ;-)
|
| An interesting derivative of XL is Tao3D, which shows what you
| can do with it. https://tao3d.sourceforge.net
|
| A FOSDEM workshop about Tao3D (which includes initiation to XL):
| https://www.youtube.com/watch?v=uE9LwSuZD64
|
| The design philosophy, and why it's not "just another Lisp" is
| here:
| https://xlr.sourceforge.io/Concept%20Programming%20Presentat...
| runlaszlorun wrote:
| Well, quite an ambitious and impressive piece of work. And as I
| mentioned elsewhere here, reading your history made me feel a
| lot better about not having a ton to show after 3-4 years,
| haha.
| pkjens04 wrote:
| How does this compare to http://flexipl.info/
|
| Iirc backend and goals seem quite similar.
| mapcars wrote:
| I never heard about XL and it looks very interesting, the DSL
| capabilities remind me of Rebol/Red, but it looks like XL has a
| proper type system and compile-time optimisations.
|
| What is the current status the project? Is there any ongoing
| work and plans?
| runlaszlorun wrote:
| Anyone know of other languages using pattern matching as a
| foundation?
|
| I've come across Refal[1], who's creator Valentin Turchin seems
| like someone who hasn't gotten the recognition he maybe deserves.
| As an aside, his son Peter Turchin does some interesting work in
| a different direction that's def topical these days.
|
| I know SNOBOL gets labeled as one.
|
| Would Prolog count? I haven't actually written any myself. They
| def make a strong appearance in Erlang, though it isn't the first
| thing that comes to mind if describing. There's XSLT of course.
|
| Any others?
|
| I think if one were only able to pick one metaphor for a
| language, I think a strong case could be made for:
|
| pattern => behavior
|
| [1]https://en.wikipedia.org/wiki/Refal
| c3d wrote:
| Check out Pure. https://agraef.github.io/pure-lang/
|
| This was what convinced me to switch to LLVM. I now regret that
| decision, but at the time, it sounded like a lot of fun.
| jinwoo68 wrote:
| Prolog is based on "unification" in large part, which can be
| considered advanced pattern matching.
| shrubble wrote:
| Are you using pattern matching in the sense of Standard ML and
| the ML family of languages?
___________________________________________________________________
(page generated 2024-02-21 23:01 UTC)