pseudo-lang / pseudo

transpile algorithms/libs to idiomatic JS, Go, C#, Ruby
MIT License
685 stars 43 forks source link

Why has dev stalled? #22

Open DustinWehr opened 5 years ago

DustinWehr commented 5 years ago

Is it merely the usual reason (time/money), or have you, to some extent, lost confidence in the ideas? I think many of the 625 people who starred this project, including myself, would be grateful to hear what your current thinking on it is.

I see that your using Nim now. I was recently reading the Nim docs and was very impressed. I told my boss: "it seems to have all the good parts of Scala, without the annoying dependence on Java". (note: I'm aware of Scala Native, and the main codebase I work on currently complies with its requirements, but in doing so forgoes the use of many popular Scala libraries, which tend to use new language features as soon as they're available).

Perhaps you are satisfied enough with Nim and Python as your go-to languages to abandon the more-ambitious/idealistic goals of Pseudo? I can imagine myself going down that path (abandoning my ideas that are similar to yours for Pseudo).

alehander92 commented 5 years ago

Well, I worked on another projects and I never got to really upgrade Pseudo. I am sorry for that!

I do use Nim indeed. I agree: it's pretty nice, I love its metaprogramming power and I also have big hopes for its type system. It's very easy to interop (I work on codebase targetting the JavaScript and C Nim backends) and it's still kinda easy to write.

I think the Pseudo plan is still valid for some usecases: it makes sense to be able to "export" algorithms and small libs in other languages. On the other hand, the idiomatic part is hard: The best libraries are the ones designed with the target language good parts in mind. So the scope of Pseudo might be more limited: port the "logic" itself, but wrap it manually in better DSL-s. Still, there are things I would change today.

I actually want to bring most of the things I like to do in Python in Nim, but I haven't thought about Pseudo a lot. I see some possible variants

Ryuno-Ki commented 5 years ago

What about Emscripten? IIRC it can target different programming languages as well. Personally, I'm not such a big fan of typing systems …

DustinWehr commented 5 years ago

@Ryuno-Ki Pseudo produces source for humans, not just for execution. Emscripten doesn't have that goal, right?

Ryuno-Ki commented 5 years ago

No, I meant as a backend (instead of Nim)

alehander92 commented 5 years ago

yeah pseudo is kinda confusing, I usually call frontend the input code: it is currently Python, but one can write another frontend for the language he wants: e.g. Nim etc. I call backend the code generators.

Well, I also used to be a fan of dynamic languages but I think type systems and typed languages have evolved a lot: Python's mypy and TypeScript are good examples of this trend. I think a lot of stuff that is easy to express in a dynamic lang can be expressed similarly easy with different patterns in powerful typed

Ryuno-Ki commented 5 years ago

My problem is not what typings help you to solve (IntelliSense suggestions, interface confirmation etc), but that people tend to not type check then. Plus, someone taking advantage and throwing things at it.

Plus, I don't feel comfortable with having a compile step. It makes me feel detached from my code.

I can see its value in larger software project, though.

DustinWehr commented 5 years ago

@Ryuno-Ki sorry I misunderstood. @alehander42 mypy is pretty great. My only complaint is that they haven't implemented recursive types yet, but it's on their list.

DustinWehr commented 5 years ago

@alehander42 I've been thinking along the same lines as you, off and on, for years now. I have a project called NoLockin (I do like the name "Pseudo" better), which I've not yet made public, that is similar in many ways to a combination of Pseudo and your earlier Hivemind. I'm dogfooding the whole syntax-agnostic thing by writing a self-hosting compiler. For that reason, I'm currently using an ugly lispy concrete syntax. If you're interested, I'll expedite making it public.

use a custom source language which can be optimized for this goal and use backend-specific hints

What do you mean by backend-specific hints?

Still, there are things I would change today.

Are those covered by your following bullet points? If not, what things?

On the other hand, the idiomatic part is hard: The best libraries are the ones designed with the target language good parts in mind. So the scope of Pseudo might be more limited: port the "logic" itself, but wrap it manually in better DSL-s.

I think you're right, but I don't think that's very limited. A more significant limitation, but also an easily circumscribed one, is that Pseudo/NoLockin will never be appropriate for quick and dirty coding, which benefits a lot from over-constrained, tightly syntax-coupled features. I might go as far as to recommend NoLockin only for one's version 2 of a module.


Mostly I just want to be able to write code that can be read by any programmer, that isn't encumbered by unnecessary baggage the second I start typing, and that won't be abandoned/ignored for superficial reasons by others in the future.

alehander92 commented 5 years ago

Backend-specific hints: e.g. you write the source code once, but you add some hints / directives specific to the Ruby or Java generation: this is kinda useful as sometimes the compiler has choice between different output patterns (e.g. translate tuples as class/array) and the user might know better, however this might be a part of an additional config file.

They are kinda covered: I'd use language with type annotations (even if I use Python, it would be with mypy) as a default frontend. I'll probably spec it a little bit better. I am not sure if multiple frotends is a good or bad idea: I like it because it gives choice, but this might be too much for users?

Oh, your project sounds very cool. I'd love to see it of course, but take your time with it. The pluggable syntax thing is interesting, I should have experimented more with Hivemind. However something like this depends a lot on good editor plugin support too.

The Hivemind idea becomes more interesting if you add a macro system: on the one hand it sounds harder for +1 syntax, but on the other hand if it just works on the AST it will automatically be available for all targets.

A macro system is one of the pro-s of using a language like Nim as a frontend, as python's metaprogramming is harder to translate: on the other hand macros can be used easily to "generate" normal code which would be translated, but sometimes translating them (as dsl-s) directly would be very hard. Still, I think even generating code is useful: e.g. you can generate boilerplate for your target languages and keep the original code even cleaner.

alehander92 commented 5 years ago

The error system is a problem: having a safe source language really helps, as even if you compile to language with different type systems, you should benefit from the original safety. So if a Pseudo/NoLockin system can analyze all side effects and errors correctly this would be a new +: you can generate Ruby but you'll know that your code is checked by a strong type system. Using exceptions can work, as there are effect systems which can analyze them, but it might be harder to translate: e.g. to C or Go, you need to map them to error codes and generate the bubbling code. I wanted to write that as a middleware in Pseudo :) On the other hand Result types (as Haskell or Rust) are also not always perfect and are more atypical for the programmer.

DustinWehr commented 5 years ago

@alehander42 Haxe has the safe source language property you mention. My main gripes with it are not that it bundles a runtime with GC (that's a smaller gripe), but with things that are a consequence of its having evolved in the same way that other programming languages evolve, including:

  1. Current concrete syntax influences new features.
  2. Ease of adding and usefulness of a new language feature is most of the motivation required to decide to add it.
  3. It has a fixed concrete syntax, which inevitably turns off some programmers who would otherwise be interested. I think the value of a project like Pseudo/NoLockin (a "language abstraction layer", one might say) is lost if it can't credibly be perceived to be relatively independent of taste, since then you'll have more open source "language abstraction layer" projects spin up, which would result in the same duplication of effort that we get from having many 90%-similar programming languages.

Macros are an example of a feature that's very useful to individual programmers and, up to a point, relatively easy to add, and the Haxe community is very proud of their macro system. But I suspect that macros, with the possible exception of very limited macros, are contrary to writing "language-agnostic" code, as they result in different programmers writing different incompatible versions of roughly the same abstractions. I think Python is closer to fulfilling the goals of NoLockin than Haxe is. C++ is closer in a different, disjoint way, by not killing simpler features in favor of more-general but more-complex ones.

You mention exceptions and effects. I'm content with excluding Haskell as a target (though I admit I've gone back and forth on this), for reasons we could get into. So NoLockin would be language-agnostic only with respect to a certain space of programming languages. My attitude is that, if the idea has merit, it'll show even if it's not at first carried out as generally as it could be.

DustinWehr commented 5 years ago

@alehander42 are you familiar with Mono? https://www.mono-project.com/docs/about-mono/languages/

alehander92 commented 5 years ago

@DustinWehr

Haxe is very cool. I haven't used it or stuided it in depth. Its type system seems nice, but I think it's a bit more pragmatic than what I have in mind: I really want to experiment with several not-very-mainstream type-related things to check. (Again, not an expert in Haxe, correct me if I am wrong: their type system might be more useful than my plans).

A limited runtime might be needed for Pseudo too: but I hope it's very limited, and that it doesn't include a GC. This makes compiling to C/Rust problematic: I still don't have a good solution except some rust-like compile time memory type system.

I absolutely agree with your points: a new language brings many problems. However, I plan on keeping Pseudo as a lang-independent format that can be generated by many other languages and frontends: this doesn't mean one can't try to design a language specifically targeting it.

Let's look at the cons of using a subset of language as Ruby or Nim:

So, we have a lot of pro-s and con-s and I think the best solution is to have both:

Such a language can be very minimal and I have to admit it's very interesting for language design view: I want to tackle this, but this might be just my theoretical interest in language design, and not a real need. It's very hard to assess if it's a good decision.

Such a language can theoretically still have swappable syntax-es as Hivemind: I don't plan on doing that as I am afraid it might be too much to newcomers, but maybe it's not a bad idea. Hivemind's original prototype was for a very simple language.

It can do whole program analysis, as the programs would be small, the biggest problem is that it's very hard to make sure the target actually does something as safe as we promise.

The features would be just functions, several kinds of types, the stdlib (which can be mapped directly to the pseudo stdlib) and basic constructs. Type checking is mostly the compiler's job and just similar to adding checkable documentation.

I am not sure about that: Go, Rust, C + many functional languages is too big of a group to exclude. Possibly exceptions can be translated to errors, but it might be also more obvious where an error is by annotating it in the code: this is an open problem. Still, other frontends can translate exceptions to errors probably easily.

Again, this is my thought process and it's mostly about an (interesting for me) pseudolang. Pseudo itself doesn't change a lot! It still does relatively the same thing

alehander92 commented 5 years ago

@DustinWehr I know of .NET and I assume that Mono supports .NET languages and they can interop on it (similar to JVM languages)? This is cool, but my goal with Pseudo is mostly to be able to generate programs / libs with readable code and the same behavior in as many languages as possible. Interop is kinda possible, but it works on a different level.

I wonder if a functional language isn't a better frontend for Pseudo: it can be analyzed more easily and translated to even more languages.

alehander92 commented 5 years ago

@DustinWehr After all, isn't NoLockin also language? It seems to me on the same abstraction layer as Pseudolang, it's still not valid Python or Ruby etc. If you're talking about having Python/Ruby-like syntaxes, I think this is still far from having an actual Python-to-NoLockin compiler and I think it can work in the same way for a hypothetical pseudolang: in this case our differences might be more in the nolockin/pseudolang language semantics and nolockin/pseudo format?

DustinWehr commented 5 years ago

@alehander42 sorry for my delayed response. I missed the github notification email.

I know of .NET and I assume that Mono supports .NET languages and they can interop on it (similar to JVM languages)? This is cool, but my goal with Pseudo is mostly to be able to generate programs / libs with readable code and the same behaviour in as many languages as possible. Interop is kinda possible, but it works on a different level.

I mentioned Mono because when I was reading about Microsoft's Common Language Runtime, I encountered ideas in the same spirit as mine. I think they've accomplished some of the same goals, but unfortunately it's all tied to the .NET ecosystem (quite unnecessarily, as the Mono devs would point out). Unfortunately, I think even the loose association with Microsoft will seriously hamper adoption of Mono (see https://www.mono-project.com/docs/about-mono/concerns-about-mono/).

Is "mostly to be able to generate programs / libs with readable code and the same behaviour in as many languages as possible" your fundamental goal? For me it is the best concrete goal I can think of to achieve a fuzzier and loftier goal (well, best and most interesting, if I'm being honest; I do work in language design), which is basically to make the open source software engineering community more efficient. Between, in fuzziness, that goal and the concrete one, is something like "to decrease fragmentation / duplication of effort in open source software engineering".

I am not sure about that: Go, Rust, C + many functional languages is too big of a group to exclude. Possibly exceptions can be translated to errors, but it might be also more obvious where an error is by annotating it in the code: this is an open problem. Still, other frontends can translate exceptions to errors probably easily.

I'm not ok with excluding Go, Rust, and C!! (what do you mean "many function languages"? I can't think of a functional language with effects but no exceptions). I'm tentatively ok with permanently leaving Haskell-target support for someone else. What I didn't express well in my last message is that I'd like to get NoLockin fully working for only target languages with exceptions (and probably also GC), before moving on to the harder problems involved in being agnostic about exceptions and GC. In short, I want NoLockin's milestones to include a working product.

Such a language can be very minimal and I have to admit it's very interesting for language design view: I want to tackle this, but this might be just my theoretical interest in language design, and not a real need. It's very hard to assess if it's a good decision.

Yeah... sigh. Well, that's why I was so heartened to find Pseudo. Apparently over 600 others think it's a real need. I realize I might be too-broadly interpreting the subject of that paragraph of yours.

@DustinWehr After all, isn't NoLockin also language? It seems to me on the same abstraction layer as Pseudolang, it's still not valid Python or Ruby etc. If you're talking about having Python/Ruby-like syntaxes, I think this is still far from having an actual Python-to-NoLockin compiler and I think it can work in the same way for a hypothetical pseudolang: in this case our differences might be more in the nolockin/pseudolang language semantics and nolockin/pseudo format?

Well, I wouldn't be able to sleep at night knowing I introduced another general purpose PL into the world. I'd be fine with calling NoLockin a "pseudolang". I think I prefer "protolang" or "language abstraction layer", though. A NoLockin program is not executable on its own (forgive me if I've said this already). It would be executable as a target L program when combined with a default mapping of NoLockin-abstractions to L-implementations (which I think is something you're working on, in Pseudo), in the case that the only abstractions you use are ones handled by the default mapping (so mostly standard library stuff). Without a default mapping, to compile to L you have to write a (usually small) number of L-implementations of functions/types/etc. Most of those will be straight from L's standard library (primitive types, collections, etc), but some can be more complex if it's expediant (Note: I think this is vital for a proto/pseudo lang, for the sake of small-scale, low-developer-overhead uses). For example, the minimal version of NoLockin, MiniNL0, that I'm using to compile the first self-hosted compiler, requires L-implementations of standard library things like strings and integers, but also an L-implementation of a tiny abstract datatype called StrTree, which is a tree of tokens and string literals.

A python-to-nolockin compiler would be a project to consider in the future, if less-ambitious goals are successful.

alehander92 commented 5 years ago

@DustinWehr

However, I plan on keeping Pseudo as a lang-independent format that can be generated by many other languages and frontends: this doesn't mean one can't try to design a language specifically targeting it.

I see, but you have to remain assured: Pseudo and Pseudo-lang are different projects. I intend to keep Pseudo with the same philosophy: a language-independent layer between languages.

Pseudo is an independent project: it should be a suitable target for many language(subsets of them!) and to generate code in as many languages as possible.

Pseudo-lang might be a language dev experiment, might be a custom language, it might not happen: it doesn't matter: everyone can build a custom language targetting X. I agree it might seem that pseudo-lang might be the default choice: you're right, I might need to change the name or to demonstrate well that it's equally important as pseudo-python or pseudo-lisp.

However I still wanted to brainstorm: if my goal is to build algo/libs that can be reused everywhere, functional semantics seem best: they are easier to analyze and you can easily transform them to more traditional code in other languages. They can also give you more safety: this is very cool, if you target less safe languages: these are all + and -s of restricting input languages. Maybe we can have both: we can have a functional Pseudo subset, which is targetted by A which uses less mutability and a smarter type system and general Pseudo which can be easily targetted by most languages.

However exactly because of practical reasons I suspect restricting the input languages is ok(maybe even to pseudo-nim or pseudo-functional-python): functional programming is big these days, a stronger type system gives you a lot.

If the idea makes sense: people/pseudo contributors will add support for more mainstream languages: however it's a strong foundation and it solves less problems , but in a more powerful way

general Pseudo

functional Pseudo

Again, this is about Pseudo semantics: not pseudo-lang, pseudo-lang might not exist: however a pseudo-A language would be almost as custom as pseudo-lang.

A NoLockin program is not executable on its own (forgive me if I've said this already).

It doesn't matter: it is compiled to a L program: this mean it's a valid program. And you use a custom syntax/language to write it: this is exactly a new programming language.

If you're not, how do you generate NoLockin currently?

alehander92 commented 5 years ago

tl;dr

Pseudo might require more functional/type stuff.

Still, it's language independent: you can use custom language targetting it: but having less input languages and targetting more languages seems more useful/cool to me.

alehander92 commented 5 years ago

@DustinWehr sometimes it might be hard to explain things like that without quick feedback: if you are interested in more discussion we can chat(gitter / mail), but if you prefer forum-like discussion, we can continue here