cliffclick / aa

Cliff Click Language Hacking
Apache License 2.0
272 stars 21 forks source link

Interface proxies for deeper-complexity-budget features and code-as-specification conveniences. #21

Open jnorthrup opened 2 years ago

jnorthrup commented 2 years ago

Something coming out of the discussions about operator overloading was a healthy amount of bias and opinions regarding the "complexity budget" for one if not both of the issues I have opened up here #7 and #13 which are primarily about adding value through potentially toxic amounts of syntactic sugars.

At ground zero syntactic sugars are for the most part cheap and inline-able functions.

Despite the minimal consequence to language design, or perhaps to the advantage of willingly socializing source-to-source extensions, I'm going to suggest that eliminating base features along the lines of #7 and #13 is to the benefit of streamlining; where there would always be a measure that has gone too-far for n-1 users of the language if they were intrinsic complexity of the language.

My assessment therefore is not to fork the language towards these ends but to follow the evolution of javascript and its closure compiler, to just accept that a stable and robust grammar baseline arrives from a low complexity design and anyone with common sense can make the call to build or port or adapt syntax sugars among successful models like Elixir to Erlang for instance, or Typescript and ECMAscript.

I think closing the other 2 issues is a boon to "doing it right" and streamlining the initial proofs of the language.

cliffclick commented 2 years ago

👍 I heartily agree!

jnorthrup commented 2 years ago

What if anything makes source-to-source compilers cheaper to build and exemplify ? intellij-community source code as a language dependency does not spring to mind.

cliffclick commented 2 years ago

Machine code generation is a long large complicated topic, with many thousands (10's of thousands?) of PhDs driving it. Its hecka lot easier to generate source code, and it can be done with a much smaller education level and effort level.

Ultimately SOMEBODY has to make machine code, so you can't skip that step. The Buck Stops Somewhere.

Lots of folks say "generate C code" or "use LLVM", both of which lose out to Java's JIT tech (but in different ways). I did the Java JIT, so I lean that way.

jnorthrup commented 2 years ago

I used a track/sector editor for years to write machine code.

my question should have used s2s "transpiler" not compiler.

ok so question about modular language design, if I'm encouraging AA to satisfy the ever-popular niche of golang++ or "Jferrous-oxide" by deferring language complexity budget items to s2s transpilers are there architectural strategies that are foreseeably cheaper than re-implementing the entirety of the parse tree (e.g. copying and pasting AA frontend wholesale ) in order to reason about the compilation graph and then and only then add language features to reify as AA ?

cliffclick commented 2 years ago

no, for much of the same reasons i listed above. source-2-source requires the author to well understand both languages (AA and e.g. Clojure) - but NOT need to deal with complex compiler IRs with their endlessly subtle invariants (and also not deal with registers, lifetimes, machine code, etc).

jnorthrup commented 2 years ago

by no( alternatives ), I think you are saying that for an s2s transpiler written in AA for the purposes of building a hypothetical AA-front with syntactic sugar extensions and metaprogramming additions one would first checkout the current version, copy some arbitrary collection of sources wholesale, and modify those in place to parse and tokenize, ( presuming the code is the AA spec and not the docs or the specs themselves until so scribed entirely ) ...

but then also perform the mental accounting of which files are and are not viable and relevant, and thereafter switch to tracking language changes and not the AA source tree changes more and more as progress on the AA and AA-front proceed at different rates for different purposes.

no, meaning the alternatives are few.

cliffclick commented 2 years ago

If the intention is to change the basic parsing of AA, I would instead propose you write a s2s transpiler: you write a parser for language X and emit language AA. The parser for language X is not (necessarily) based on the parser for AA, so you are not hacking the AA source. This is the same path you would take if e.g. transpiling from XML or SQL to C / Fortran / Java.

If the intention is to allow tight interspersing of AA code and some other language (as is common in embedded DSLs), I propose that the existing operator overloading plans, plus a judicious use of 'eval' will do the trick. Embedding tricks for e.g. SQL in C (which already exist and are well known) would work just as fine here.

jnorthrup commented 2 years ago

I think I should de-emphasize the need for an immediate timeline consideration. Issue title tweaked.

not discussed here so far the strength/consistency of AA specification over time: Assuming that HM typing and front-end in AA is bootstrapped with Interfaces by Interfaces, code-as-a-specification works for the long-haul for the same presumed s2s features if the interfaces are the spec doc and not the impls. code-as-specification makes borrowing the code reasonable to offload the responsibility of documenting those AA features included in a s2s transpiler. it also saves time and effort.

Also simple and straightforward is having dynamic interface proxies as a supported feature to complement specifications as Interface. This is what should have preceded AOP in java, but it didn't.

In this instance, I can absolutely proxy an interface, change the name of the AA language to be "X" in anything that reports the language name, and perform low-cost exploration of language features and testing which tracks the Interface's codebase lifecycle so that I don't have to do mental accounting or freeze deps based on a particular implementation timeframe of AA.

maybe the outspoken conscientious complexity budget objectors demand a language with no unseen super-scoped operator overloading, or simply none, in any part of their low complexity code guarantees passed along to users/investors etc. They can proxy an interface without using overloads, to guarantee that the use of operator overloading is going to meet their specification by aborting in that section of the parser. this opens a lot of doors for narrowing the language specification down to a set of arbitrary proofs without buggering the back-end features.