Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design Meeting Notes, 11/9/2022 #51809

Closed
DanielRosenwasser opened this issue Dec 8, 2022 · 6 comments
Closed

Design Meeting Notes, 11/9/2022 #51809

DanielRosenwasser opened this issue Dec 8, 2022 · 6 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

Post-Modules Follow-up

Semantic Lints

#51456

  • The last semantic rules we have are few.
  • Getting rid of all semantic rules would speed our lint time up a lot.
  • No unnecessary assertions takes up a decent amount of time - but it seems arguably good to have.
    • Getting rid of assertions over time helps improve quality of the code.
    • Switching to rely on narrowing is better because assertions left alone can get stale. Then future changes to a type may be masked by the stale assertion.
  • Maybe we should have "no unnecessary assertions" in the compiler itself?
  • What does it mean to be "unnecessary"?
    • Lint rule says "textually identical".
    • User could be thinking "up-casts".
    • We could make it better with our view of structurally identical.
      • Could see this as a --strict rule; however, as we start to think about "what is slow to run", it is hard to imagine more modes where we say "do more checking for the 99% of cases where this will succeed".
      • Though identity is usually pretty fast.
  • Why is this so important?
    • Linting in the editor is slow with semantic rules.
  • Conclusion?
    • Revisit.

Remove ts.Map and ts.Set

#51439

  • Objections?
    • None.

Bundle Splitting our Executables

#51440

  • tsc.js and tsserver.js are not usefully importable - can switch those into ESM if we want!
  • Why?
    • esbuild (our new bundler) makes it easy to do bundle splitting if your output target is ESM.
  • If we ship tsc.js and tsserver.js as CJS wrappers that invoke import("tsc.mjs") and import("tsserver.mjs"), both tsc.mjs and tsserver.mjs can share lots of the same guts.
  • Shaves off 7MB from our package size.
  • Feels like it may be difficult to work with over time, has caveats.
  • Have to drop Node 10 support.
  • Feels like an "uncomfortable yes"

Diagnosing Expensive Types

  • People often ask how to "debug" types - especially types that are expensive.
  • There's types that "pull" on a thread that goes deep in its own self-instantiation, and then there's types that are kind of "executable", that cause a lot of work to be done.
  • Today we have instantiation limiters
    • Depth limiters - how deep instantiation is going (kind of like a call stack)
    • Type creation limiters - how many instantiations of any type has occurred during instantiations.
  • These are hard limits - "blunt force instruments" - that cause an error; but we don't tell tell you about types that get close to those limits.
  • What if we had --typeDiagnostics that could provide a table of the most expensive types?
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Dec 8, 2022
@lemanschik
Copy link

lemanschik commented Dec 8, 2022

You should take into consideration

  • refactoring away from classes into functions that get composed out of functions directly action able?
  • the usage of Readable Writable stream for the processing?

Why?

if you would replace your internal queues with Web Streams this would take away some of the complexity to understand your code also it would be more easy to change the limits via water marks and re piping the streams overall the project would reach the goal of putting discipline on assignment so getting more functional

and would move away from classes and data structures applied over data. in fact classes are a not so good form of namespaces in ECMAScript you should try to get to composition over inheritance

that can reduce the complexity again a lot out of my view. it solves at last a lot of thinking issues when you iterate over the code base it helped me for example a lot to resolve deadlocks in vscode.

benefits

it reduces the amount of context switching between docs and all other documentation places while reading the code.
if it would be simple data manipulating streams i could read that code and understand directly what it does.

in general there is only one thing that can be done with Data it is ruin it as soon as you apply any additional structures or objects or classes around the source data and do not use it as it is you ruined the data.

Example Refactor a Class into a Function that you can even compose with injections

class megaImplementation {
  constructor()
  method1
  method2
}
// default implementations
const method1 = ()=>{}
const method2 = ()=>{}
const megaImplementation = {
  method1
  create
  method2
}

//functional composition aka currying pattern
// Injections
const megaImplementation = (  method2 = { injected: () =>{}} )=> /** type {} */ ({
  method1
  create
  method2
})

//includes type casting as () is needed to directly return object without return keyword anyway.

The above example includes that a js file used in such a way with jsdoc is most time also relativ simple intrinsic does most out of const. same for other types via jsdoc keyof typeof and then using const type casting gives you nice JSDOC only based types out of the useable code directly

with // @ts-check added on top you even do not need a additional tsconfig.json to get full typescript support.

onion types and compositions also result in small JSDOC overhead as you can use typedef for the imports if needed

and then use onion types via & operator. in the @type annotation. directly also you can use objects there
it is more then productive i alone was able to maintain the whole typescript codebase which is not a easy task

which you will agree.

the above pattern leads into a massiv code reduction while keeping the features complet also they lead to more realistic types less failures and so on. simple because there is less conversation between the source and the running code.

@DanielRosenwasser
Copy link
Member Author

I actually don't believe these suggestions are applicable to the TypeScript codebase.

@lemanschik
Copy link

@DanielRosenwasser they are in fact they are i try to write even a book about that via porting a old but gold talk from the creator of closure script https://www.infoq.com/presentations/Simple-Made-Easy/

in fact i will even take typescript as a example in the ecmascript version https://github.com/lemanschik/simplicity-made-easy it is about the != of simple != easy. which is a key concept to get code reuse and overall code reduction.

As i in fact moved my whole Cloud ide into the browser without any need for nodejs anymore i can tell you it is possible.

The book will show a demo of a on load typescript refactoring cherry picking commits based on conditions directly from the github repo so it fetches the git commit meta composes the text content from the cherry picks and loads that.

the result will be a simple typescript version which is not easy but simple. At present typescript is what is referenced as easy to use but it is not simple by design. And that adds Complexity. We see that all over if it would be a collection of good designed Modules Compose able via Functions this would not need any configuration.

It does by design then do what it is expected to do.

It archives then all goals which it does currently not do:

What matters in software is:
The answers to these questions is what matters in writing software not the look and feel of the experience writing the code or the cultural implications of it.

  • does the software do what is supposed to do?
  • Is it of high quality?
  • Can we rely on it?
  • Can problems be fixed along the way?
  • Can requirements change over time?

the solution for the above is simple but not easy.

Build simple systems by: Abstracting - design by answering questions related to what, who, when, where, why, and how. Choosing constructs that generate simple artifacts like modules that do not reference other modules without a unified resolver method that produces static in memory references... Simplify by encapsulation via composition of functions and streams.

@DanielRosenwasser
Copy link
Member Author

@lemanschik, I don't have a more ideal place to post this, but these recent responses are examples of a pattern of comments you've been posting on our issue tracker for a while now. While we understand that the issue tracker often presents the opportunity to brainstorm, we've been finding that your comments are, in the majority of cases, off topic, hard to comprehend, and very frequent. The repo has enough activity as-is and I'd really ask you to refocus your efforts into producing on-topic, readable comments with an actionable point to them.

Our expectations here are perfectly in line with the expectations we place on our new issue templates. We need to optimize issue reports and discourse for the sake of everyone involved in TypeScript. We need to see a change where your participation is clear and constructive on relevant issues. If we don't see that, we'll have to restrict your ability to post on the issue tracker.

@lemanschik
Copy link

lemanschik commented Dec 8, 2022

@DanielRosenwasser was

  • refactoring away from classes into functions that get composed out of functions directly action able?
  • the usage of Readable Writable stream for the processing?

i had also no better place to bring that up as the issue tracker in fact that is the most best place to put that up when you iterate on that. At last that is my opinion but i get the pattern. So your development flow is more important then the overall result correct? I mean if you would design your code more simple you would not even need this iteration styles and guard rails development with the test stack. If you guess posting here is fun for me that is not the case.

i do it because it is needed to not waist years and also not waist my money.

the fact that i popup all that issues should also indicate that there is something inherently wrong i am one of the biggest brains in terms of Computing that exists on earth and is still alive. I have better things to do then fixing other people's code. So i try to tackle the issue at the core it is education out of my view and that is not your fault your only fault is when you ignore this facts now. I am that kind of person that can easy charge up to 3000 per hour that is possible because i get payed based on value not on time..

and as you maybe see i try to improve the language and wording incremental. And i hope that i soon as sayed come up with some better communication formats. But at present this is what we both got today.

the post are also only as noisy because you give no constructive feedback other then change wording change information format. Change PR style. All this does not solve anything. It is not Productive.

i even try to compress the reasoning as much as possible to make it more simple to think about that. Maybe i compress to much i do not see the direct failure.

A answer like frank maybe your correct you did 30 years of research into fundamentals and your language implementer you implement nativ code into v8 and design overall chromium engineering processes. would help a little bit. Then you start simply experimenting via applying that refactoring to small parts of the code base and then directly feel that you did the right thing. I understand VM's and the V8 Engine including the details.

All in your team will see the results it will incremental reduce the amount of chor commits to near zero as your fundamentals will not change your a compiler.

Streams are by the way simple forms of Iterators Generators so they represent the concepts of a Observable including locking so they abstract the notion of time. It simply gets done when it should get done. Refactoring to streams would mean turn all parser methods into independent modules or functions and then start connecting them via event based streams that you can compose via a chain i will supply a final pr in some month so you can simply see the result and call it day. so it means drop everything that is not a const or function also the interfaces and all that namespaces

classes are in fact only pure namespaces.

@RyanCavanaugh
Copy link
Member

refactoring away from classes into functions that get composed out of functions directly action able?

The type checker doesn't use classes.

the usage of Readable Writable stream for the processing?

What does this even mean? A stream of what ? Which processing step? You can't just say "Use streams" at a project based on a global analysis model and expect that to be understood as a coherent proposal.

I just want to state this plainly so there is no confusion: If you don't stop posting comments which don't make any apparent sense (I'm setting a very low bar here; you have enough technical sense to understand what this means), you'll be blocked from the repo, because it's derailing too many conversations and creating too much noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

3 participants