Skip to content

Instantly share code, notes, and snippets.

@wycats
Created October 25, 2022 23:11
Show Gist options
  • Save wycats/6800716eb6744f63d9b9396670d5c625 to your computer and use it in GitHub Desktop.
Save wycats/6800716eb6744f63d9b9396670d5c625 to your computer and use it in GitHub Desktop.

Revisions

  1. wycats created this gist Oct 25, 2022.
    111 changes: 111 additions & 0 deletions sketch.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,111 @@
    # Making `unique-id` a importable function

    ## The Use Cases

    ```tsx
    import { uniqueId } from "@ember/???";

    <template>
    {{#let (unique-id) as |id|}}

    {{/let}}
    </template>
    ```

    ```tsx
    import { uniqueId } from '@ember/???';

    class MyThing {
    id = uniqueId();
    }
    ```

    ## The Constraints

    1. The behavior of `(unique-id)` in classic mode must be the same as the behavior of `uniqueId()` in
    `<template>` mode.
    2. The `uniqueId` function must be the same function in both use-cases described above.
    3. The result of `uniqueId()` in a `<template>` must not change after the expression was initially
    evaluated.
    4. Other importable "helpers":
    a. hard constraint: should eventually come from the same package name (or, some coherent package structure)
    b. soft constraint: people will find it weird if we ship `uniqueId` but not other similar helpers
    that are in a similar predicament.
    5. Modifiers and components should also ultimately be imported from a coherent package structure
    that includes whatever we do here.

    ## Importable Things

    ### Ember.Template.Helpers

    | Name | Type | In `<template>`? | Importable? |
    | ---------------------- | ------------------------ | ---------------- | ---------------------------- |
    | action | | ☠️ | ☠️ Uses `this` from template |
    | array | pure helper | 😀 | ✔️ |
    | hash | pure helper | 😀 | ✔️ |
    | component | | 😀 | ✔️ |
    | - takes dynamic string | internal | ☠️ | ☠️ |
    | - take a component | ??? | 😵‍💫 | ??? |
    | helper | ??? | | |
    | modifier | ??? | | |
    | concat | pure helper | 😀 | ✔️ |
    | debugger | control flow | 😀 | ✖️ |
    | each | control flow | 😀 | ✖️ |
    | each-in | control flow | 😀 | ✖️ |
    | fn | probably keyword | 😵‍💫 | 😵‍💫 |
    | get | pure helper | 😀 | ✔️ |
    | has-block | control flow | 😀 | ✖️ |
    | has-block-params | control flow | 😀 | ✖️ |
    | #if | control flow | 😀 | ✖️ |
    | if | control flow | 😀 | ✖️ |
    | #unless | control flow | 😀 | ✖️ |
    | unless | control flow | 😀 | ✖️ |
    | in-element | internal component | 😀 | ✖️ |
    | input | classic component | ☠️ | ✖️ |
    | let | control flow | 😀 | ✖️ |
    | link-to | classic component | ☠️ | ✖️ |
    | log | ??? | | |
    | mount | control flow | 😀 | ✖️ |
    | mut | keyword (references) | ☠️ ? | |
    | on | modifier | 😀 | ✔️ (maybe keyword) |
    | outlet | control flow | 😀 | ✖️ |
    | page-title | ??? | | |
    | textarea | classic component | ☠️ | ✖️ |
    | unbound | legacy | ☠️ | ✖️ |
    | unique-id | non-deterministic helper | 😀 | ✔️ |
    | yield | control flow | 😀 | ✖️ |

    **NOTE**: inline `if` and `unless` are control flow because they "auto-arrow" their expressions.

    #### Importable Candidates

    #### Meaningful in JS

    | Name | Type | In `<template>`? | Importable? | Meaningful in JS? |
    | --------- | ------------------------ | ---------------- | ----------- | ----------------- |
    | concat | pure helper | 😀 | ✔️ | ✔️ |
    | log | non-deterministic helper | | ✔️ | ✔️ |
    | unique-id | non-deterministic helper | 😀 | ✔️ | ✔️ |

    #### Not Meaningful in JS

    | Name | Type | In `<template>`? | Importable? | Meaningful in JS? |
    | ---------- | ------------------------------ | ---------------- | ------------------ | ----------------- |
    | mut | keyword (references) | ☠️ ? | | ✖️ |
    | on | modifier | 😀 | ✔️ (maybe keyword) | ✖️ |
    | page-title | non-deterministic control flow | | | ✖️ |

    #### Unsure

    | Name | Type | In `<template>`? | Importable? | Meaningful in JS? |
    | ----- | ----------- | ---------------- | ----------- | ----------------- |
    | array | pure helper | 😀 | ✔️ | 🤔 |
    | hash | pure helper | 😀 | ✔️ | 🤔 |
    | get | pure helper | 😀 | ✔️ | 🤔 |

    Maybe we want these to be keywords because they are effectively literal notation for objects and arrays.

    ### Built-In Components

    These are currently implemented as special Glimmer resolution rules, but we don't want to make them
    keywords in `<template>`, so they need to be importable.