Hacker News new | past | comments | ask | show | jobs | submit login
The Lx Programming Language (github.com)
63 points by kick 16 days ago | hide | past | web | favorite | 46 comments

Disclaimer: Author of the language / web page speaking.

This one is hopelessly outdated. See https://github.com/c3d/xl for the current state of things. A bit of history of the language here: https://github.com/c3d/xl/blob/master/doc/HISTORY.md.

Warning: this is currently under heavy repair / refactoring, so Nothing Works™.

An interesting (if old, 2010) application of the language here: http://tao3d.sourceforge.net.

Contributions and ideas welcome.

What you did there is very cool! I am speaking for both LX as presented in the old link and the new work that you are doing.

Personally I have given up creating a new programming language about a decade ago because I realized no matter what language I create, people will not use it, it it comes from a random github page.

Also, existing languages cover almost all business needs and while languages like LX provide a lot of improvements, the cost of change seems to be greater than the cost of not having these improvements.

As for ideas, what I'd like to see in a programming language is signal-based programming: the execution flow of a program is not 'one instruction after the other' but reactions to signals. A program shall be built by wiring output signals to input signals.

I'd also like to see types morph based on run-time conditions.

The most fundamental problem of all the current programming languages is that types are too rigid and don't allow for catching all the possible outcomes. For example, a File morphs between a closed file and an opened file, however in current systems any operation can be applied to a file, irrespectively of whether the file is actually opened or closed.

I believe that the combination of signal-based programming and type morphing will increase the reliability of programs, leaving only bugs that cannot be proven to be solved due to their nature (aka like the halting problem).

I may not be necessarily correct, but I have a strong belief in the above.

> no matter what language I create, people will not use it, it it comes from a random github page.

Speaking as a fellow sufferer, how did perl, python, php, lua, ruby start getting used? They were pre-github, but jq really did start that way: https://github.com/stedolan/jq.

The key to being used is a usage: a problem to apply it to. If there's a problem that people need solved, and your language is much better than the alternatives, then people will use it, post about it, rave about it. If JSON wasn't popular, jq wouldn't be popular.

OTOH your actual interest is in more abstract ideals. This is crucially important work, but you may be right that no one will use it... instead, they'll be interested in the ideas you are interested in. Finding a needed application of your ideas will generate use.

'Random github page' means there is a plethora of new programming languages to chose from (due to easiness of sharing projects that github allows) and studying of them all to see if they solve any new issues or improve things so much that it makes economic sense to work on this new language becomes increasingly more difficult.

In the pre-github days, candidate programming languages were fewer and solved yet-almost-unsolved important problems. The more you go into the past, the easier it is to get your foot in the door.

> studying of them all to see if they solve any new issues

But you don't find them that way - you look for a solution to your problem, and you come across them. That's why they say "scratch your own itch"; someone else might have that itch too.

You search for JSON transformation, you get jq (that's how I found it, some years ago).

You're right that it was easier earlier. But there are new-unsolved-important problems all the time --- and "solutions to problems" radically narrows the search space.

The thing you are referring to with open and closed files is called typestate. Check out its implementation in the Plaid programming language: http://www.cs.cmu.edu/~aldrich/papers/onward2009-state.pdf

There was a post here on HN about typestates in Rust too yesterday. For anyone that didn’t see it: https://news.ycombinator.com/item?id=21413174

>> For example, a File morphs between a closed file and an opened file, however in current systems any operation can be applied to a file, irrespectively of whether the file is actually opened or closed.

But not in Rust. As a matter of fact anything based on intuitionistic logic could do that for you (e.g. use-only-once, must-use, etc).

My own realization that I'll probably never do anything on the frontier of language design hasn't killed my interest in designing a language, but redirected it.

These days my thoughts drift towards novelty and niche domains. What would be the most interesting way of describing a subset of things? The most fun? The most intuitive? What's a way to break a specific domain down into a vocabulary that lets you populate it while forgetting you're even using a computer?

I think there's still a lot to explore even if you aren't shooting for maximum productivity or even general-purpose programming.

You should check out Idris: https://www.idris-lang.org/

others say typestates, but Scala and Haskell have had IndexedStateT for the purpose of typelevel-state-machinery and it works really well with (somewhat lesser) boilerplate and semantics + FP. To me, it's particularly useful for anything resembling a protocol.

Signal based processing is Observables/reactive streams, which provide a sane interface to use.

This is (one of) the problem with new languages: library ecosystem access. It's why Scala/Clojure/Kotlin is one camp of languages and Zig/Rust is in another - both Java and C have a ton of great libraries written in them, with ones that add signals-first approaches via libraries.

You can look into SIGNAL, esterel, lustre, Céu... dataflow programming has been developped since the 80s and has some markets where it is extensively used (avionics, digital audio and digital art, simulation...)

Interesting thoughts about signals. Aren't callbacks somewhat similar? (As in JavaScript for example)

Having played around with XL, Tao3D and Elfe, I have to say there was/is a lot of fun to be had and some very compelling concepts and unique ideas in these projects. Its great to see them mentioned on HN. I found the parse tree approach very educational and its a very nice and powerful alternative to S-expressions. Tao3D was an very quick way to build simple interactive graphics apps and a lot of fun. ELFE has some interesting concepts for distributed computing. While I ended up using Erlang and LISP rather than ELFE it was defintely eye opening in a good way and reminded me of the fun and creativity to be had - - so a huge thank you for the past projects and good luck with the next evolution.

> I found the parse tree approach very educational and its a very nice and powerful alternative to S-expressions.

Do you have at hand a link where I can read more about this? Thank you in advance!

Well, a starting point would be this: https://github.com/c3d/xl/tree/master/doc. It's not finished, but it gives you a good idea.

For Tao3D, you have https://tao3d.sf.net.

Thank you!

I was actually looking for something specific about parse trees vs S-expressions. That would be https://github.com/c3d/xl/blob/master/doc/HANDBOOK_1-syntax....

But I'm reading the whole thing now. Very interesting language! I don't see myself using it in production any time soon, but it looks like a wonderful tool for programming languages research. Thank you again!

So I was thinking about something similar to this in the sense of a language where syntax was extendable but with making different choices. I was interested in forming some sort of base lingua franca with additional composable dialects that are available per translation unit. Imagine if you could take go know for sure you don't have any concurrency in a section or the memory management section is missing so no worries about memory management. Increasing expressiveness but also reducing cognitive load to the calling code and its interfaces and nowhere else. Want to run very complicated domain specific code and not have the guy who designs the webserver know anymore than what is nessecary to rout it great. Want to add hot code,io, complexity annotations in the code, Great(Obviously this isn't free you need good tooling and to do sampled profiling and for complexity you need to make choices about what code is complex, etc.But if we're dreaming why not dream big.). Metrics,Explicit resource bounds etc. In this context for the things most people would want i.e. concurrency you would have a readily available dialect that fits 80% of use cases which would be infrequently changed. I don't know if that makes much sense in what you have in mind but I did find what you're doing interesting.

Ok, we changed the URL from http://mozart-dev.sourceforge.net/lx.html to the github.com page. If you'd prefer a different URL just let us know. Thanks!

Since the github page is current, the (2002) should probably be removed.

Removed. Thanks!

Hows the performance compared to say C++ or Rust ?

Hmm, one might think there's a trend in how almost none of the 'programmable programming languages' catch on. Lithp, Rebol, Forth, Nemerle, this one. Perhaps it has something to do with readability being more important than writeability? Me, I find macros and implicits repulsive. Give me Zig over LX any day (Zig purposefully contains no macro facility).

They are less popular for the same reason that Go is popular: if every project is its own DSL, it becomes more difficult for newcomers to ramp up on a new project. That’s exactly what Go is good for.

> Hmm, one might think there's a trend in how almost none of the 'programmable programming languages' catch on. Lithp, Rebol, Forth, Nemerle, this one.

Uh, Lisp caught on quite well. Rebol was held back by coming out when being open source (or at least having an open spec) was expected for languages, but it wasn't until most of the interest had passed. Forth I gather was pretty popular, but fell of its peak even before Lisp did.

Of course, while not with Lisp style macros, pervasive metaprogramming was a key distinguishing feature of both Python and Ruby, which both reached fairly intense levels of popularity. And of course Perl...

> Me, I find macros and implicits repulsive.

And it's fine that that is your taste, but it's clearly not as universal as you would like to pretend.

None catch on? Depends on how you define "programmable".

Lisps are still here (think Clojure). Rust has macros. New-style C++ is mostly about metaprogramming.

Now I'm curious, what is it about macros you find repulsive?

And what's an 'implicit'?

I would trade real macros for almost any other language feature, as having them means being able to patch over whatever is missing.

The more powerful a language is, the less popular it will be. Couldn't be any other way, since only people with enough experience appreciate and feel comfortable dealing with them.

What I find repulsive is that macros are a micro-optimization for the author but a huge destroyer of readability. Consider a simple macro like "if-not" - just an inverted if. In a lanaguage without macros, the maintainer can be sure that there is only one construct like if. The eyes can skim over code, easily understanding semantics of the code without reading into it. Now consider the mere possibility that some if are if-nots: suddenly the mere ifs become a minefield for the reader. And if LX claims ability to eg modify the semantics of X.Y - it's going to be an unreadabe mess.

My point is, readability of code increases proportionately not just to the complexity and size of code, but also proportionately to the size of syntax. In a language with no macros, the latter is fixed and you get a linear dependency. In extensible PLs it's a quadratic one with an unknown second factor, jeesh! I think the approach with a more powerful but almost fixed language (eg Haskell where macros are hard and mostly used to generate boilerplate definitions) is better than a small but extensible language with every programmer on a contest of who makes a wittier and sleeker new control structure that is like the builtin ones but SO much cooler...

I don't know if you are aware of that, but at the time Pascal started emerging, the exact same arguments were presented by foiks used to BASIC that having the ability to add your own "words" to the language would inevitably lead to a mess.

Why didn't it happen? Because programmers overall are reasonable folks. So, yes, in theory, you can define a factorial function and call it "Not_a_Cat" (technically, it is true), but nobody does that.

Similarly, giving the ability to define `X in Y..Z` makes code more readable if you use it right, not less.

There are languages like Go intended to write large systems by large teams and languages like Forth that are better suited for small software written by a single programmer.

There's no need to choose between Zig and LX. Use the one that better fits the problem. If for your case that's Zig, good for you.

To be honest, the real issue with LX / XL / Tao3D is that I never ever really "finished" any implementation. By the time things were working, I had new ideas and broke things again. So except for Tao3D, I never really delivered a version of the language that was solid enough.

I'm trying to work on that now, which is why I'm presently spending so much time on documenting where I want to go. The idea is that if I first write a "spec", then a community can build to implement it, and it's not just my own (limited) time.

So if you are interested in helping right now, I'd say: read the doc (in progress) and send comment / doc fixes.

Zig has CTFE which takes the same place as macros. It doesn't need macros because it has macros.

Is there an example of a Zig CTFE function that, e.g., parses your whole Zig library, and generates new code from it ?

Java has compiler plugins, annotations, reflection and aspect oriented programming as metaprogramming tools.

.NET has T4 templates, attributes, reflection, expression trees, and F# adds code quotations to the mix.

T4 barely counts, as it's string- and not AST-based. For meta-programming to be useful, IMHO it really needs to be part of the language and base tool-chain. I certainly don't want to write code in Java, f'rinstance, that needs random compiler plug-in to weave in AOP calls, etc. But in Lisp, Prolog (and not Elixer, etc.) macros are part of "how stuff works".

Then languages like D don't have metaprogramming capabilities if using AST based one is considered a requirement.

F# quotations are nice, but it's really too bad that .Compile() doesn't use the actual compiler tool-chain and creates super-slow code. I understand due to history why it doesn't, but it certainly would be easier if F# used the Roslyn tool-chain.

The other important consideration is that most language users are not good language designers!

This strategy is kind of "punting" a lot of design work onto the user, which has a lot of downsides.

Ruby is still one of the most popular languages (especially for beginners, whom readability is extremely important for), and it was intended as a simple Lisp.

Metaprogramming doesn't make code less readable.

I am not convinced with your conclusion that metaprogramming does not make code less readable. My personal experience speaks otherwise.

Metaprogramming has a lot of "magic" associated with it which makes code hard to debug and understand sometimes.

You cite the success/popularity of Ruby as an example of why metaprogramming does not make code less readable. The popularity of a programming language does not mean that the language does not have significant warts. There are cultural and historical factors that make a language popular. Availability of web frameworks (e.g. Rails) are another powerful influence.

For the large part, Ruby code _is_ understandable/readable if you avoid metaprogramming. Once you have a large codebase and advanced frameworks that make heavy use of metaprogramming you can quickly get lost. There are lot of "effects at a distance" i.e. one library changes something and that can break something far away and potentially not even connected. Would you say your code is readable? No, the code is not readable because it runs in a totally unexpected manner.

My theory is that beginners decided to learn Ruby because it was easy to start with and it had a lot of powerful framesworks (e.g. Rails). The learning curve is gentle. But pretty soon when you start writing advanced ruby or start using advanced frameworks things can get complex.

It makes me so happy to see more rewrite based languages. Another one that is extremely cool that I almost never see brought up is [pure][1][2].

[1]: https://agraef.github.io/pure-lang/ [2]: https://github.com/agraef/pure-lang/wiki/PureIntro

The name of the language is XL, not Lx. The title of the Readme is "XL - An extensible language" and the URL ends with /xl

I'm not too sure about the dates, but the rough history is this:

LX: Langage expérimental (~1992) Ada like with "pragmas" extending the language

LX: Langage extensible (1998): Rewrite with documented object-oriented parse tree

LX/XL: Extensible language (2000) based on object-oriented parse tree, cross-language framework called Mozart, that also had a Java front-end called Moka

XL2: Extensible language (2002) based on simple parse tree, 8 node types, Ada-like in syntax

XL2: Self compiling compiler (2005?) with same 8-node parse tree, Ada-like

XLR: LLVM-based functional variant (2008-2009), same parse tree, functional, very simple, library-defined if-then-else

Tao3D: real-time 3D graphics running on XLR (2010-2015)

ELiOT / ELFE: Distributed programming (2015?), based on interpreted version of XLR

XL: Reconvergence of all of the above (WIP), all merged, implemented as a library with a tiny front-end.

I forgot to mention that XLR meant "XL Runtime" and was initially thought of as a back-end for XL2. Then it took a life of its own.

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