Coder Social home page Coder Social logo

Comments (3)

asmala avatar asmala commented on June 15, 2024

A couple of suggestions to the above, based on my experiences with clj18n:

  1. Run expand-dict upon compile or setup time. That way create-t only needs to grab a value (map of translation strings) from the dictionary by key (locale), which should make memoization unnecessary.

  2. Don't use bindings, just use closures. You can replace most (all?) uses of bindings with simple closures inside a let. Or even a def for REPL-based development. Something like:

    (let [t (create-t :en_US dict)]
        (build-window (t :window/title))
        (let [t (scope-t t :dialogues.login)]
          (build-dialogue (t :sub-title) (login))))
  3. Consider meta attached to the compiled dictionary as an alternative to the config atom.

Whether the change is worth it is probably a matter of taste, though. I personally prefer not using bindings (or behind-the-scenes config atoms) since they are arguably less purely functional than e.g. closures. And of course there's effort and backwards compatibility to consider. Perhaps something for a 2.0 rewrite?

from tower.

ptaoussanis avatar ptaoussanis commented on June 15, 2024

Hi Janne,

Sorry about the delay replying to this!

Run expand-dict upon compile or setup time. That way create-t only needs to grab a value (map of translation strings) from the dictionary by key (locale), which should make memoization unnecessary.

What I like about the memoization is allows convenient REPL dev - if the dictionary changes, it'll get recompiled. Also removes the necessity for any special compilation time/step, and removes the necessity for a "make-t" fn. Instead you can just create a t partial with the dictionary you want and use that as the closure for middleware, etc.

Don't use bindings, just use closures. You can replace most (all?) uses of bindings with simple closures inside a let. Or even a def for REPL-based development. Something like:

Yes, I'm definitely in agreement with this and would be happy to see this happen in Tower v2. I do think the create-t is unnecessary and will complicate things like a wrapper to check for changed dicts on disk. (For example, t's config arg could be a map or a filename on disk to watch for changes in dev-mode).

Consider meta attached to the compiled dictionary as an alternative to the config atom.

If it's actually useful config stuff (e.g. default fallback language, etc.), then I don't think it should be metadata. Not a problem though - I would suggest t take a config map. This will contain the dictionary and anything else necessary for t config.


Have just begun a new project that I'll be focusing on for a while, so I may be unusually unresponsive for a while. You've got commit access to Tower - so feel free to experiment aggressively on a v2 branch if you like, and we can talk about merging changes later. Otherwise I'll keep an eye on clj18n and I'll give you a shout later when my schedule normalizes.

Thanks again for all your awesome work and input, cheers! :-)

from tower.

asmala avatar asmala commented on June 15, 2024

Thanks!

If I'm hearing you correctly regarding the use of partial to replace make-t, you mean something like this:

; Assuming that we have a translate function with the following footprint…
(translate dict locale [:a.namespaced/key :a.fallback/key] "Interpolation" "arguments")

; …then we could create t with a call to partial
(let [t (partial translate dict locale)]
  (t [:a.namespaced/key :a.fallback/key] "Interpolation" "arguments"))

(partial translate …) is not significantly longer than (make-t …) so that seems workable.

I'm not sure, though, how the memoization would work or if it's even necessary. If dict is a "compiled" map of a reasonable size, then getting a translated string would be a simple matter of calling (get-in dict [locale :key]), which should be fast enough. Could you say more about why we'd need memoize and how you see that working?

Two other topics to discuss in the context of refactoring this bit would be:

  • How to pass around the configuration? (#28)
  • How to scope keys? (#29)

No hurries with this one. Better we consider our options carefully. In the meantime, Clj18n can be the Wild West test bed for ideas.

from tower.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.