Something about Lit/web components that's not written clearly on the label is the hoops you have to jump through to style elements. If you're using tailwind in the whole app, you just want to pull it into your custom elements without much boilerplate. My main app compiles a single minified app.css, it felt not so modular to now include that in every single component. The alternative is create a subclass that injects tailwind into Lit components. It'd be perfect it just had a switch to inherit everything the page already has.
By default, Lit renders into shadow DOM. This carries benefits like encapsulation (including the style encapsulation you mention). If you prefer global styles, you can render into light DOM instead with that one-line switch.
However, shadow DOM is required for slotting (composing) components, so typically what I'd recommend for theming is leveraging the array option of each component's styles:
static styles = [themeStyles, componentStyles]
Then you define your shared styles in `themeStyles`, which is shared across all components you wish to have the same theme.
oh nice! I didn't know that you can just make it use light dom.
protected createRenderRoot() {
return this;
}
And that's what it takes! I like using tailwind/utility classes so for the styles I'd need to have layers of compiled css files rather than one giant one.
The major downside of using light DOM is that elements cannot compose neatly since there's no delineating between what the component itself rendered and child content.
When you need to re-render your component, how does the component know not to replace the child content you rendered, Vs the child content it rendered into the light DOM. That's why the shadow DOM and slots were necessary, because then there's no intermingling of your content Vs the component's
This may not be a problem if you don't intend to compose your components. But if you do you will hit limits quickly
While you can easily turn rendering to shadow DOM off on a per-component basis, that removes the ability to use slots. It only really works for leaf nodes.
Pulling a stylesheet into every component is actually not bad though. Adopted stylesheets allow you to share the same stylesheet instance across all shadow roots, so it's quite fast.
Multiple-dispatch is the right abstraction for programming mathematics. It provides both the flexibility required to create scientific software in layers (science has a LOT more function overloading compared to any other field.), and the information required to compile to fast machine code.
Location: Boston
Remote: Ok with it!
Willing to relocate: yes, to anywhere reasonable
Technologies: Analytical database design and implementation, Technical/Numerical computing, Julia, Python, Elixir, C, Lisp
Resume: https://shashi.biz/resume.pdf
Email: (in resume)
Summary: I've worked with the Julia community for 9 years as a professional and a student. Just finishing up my PhD at MIT now. Have been on a lot of varied projects so far, from web development to distributed computing, looking to do some exciting work in a place where I can use my skills, pick up new ones, and have some agency. (Not necessarily Julia, any decent technology will do.)
In Julia, there is one package manager and it gets things right. https://docs.julialang.org/en/v1/stdlib/Pkg/ It's super nice to have no fragmentation when it comes to packaging. In Pkg, package states are immutable, always reproducible, and quick. Julia packages that have binary dependencies usually build them all for every platform using the binary builder infrastructure (https://github.com/JuliaPackaging/Yggdrasil). It makes cross platform installation robust and testable, and suuuper quick. Pkg really is the rolls royce of package managers.
The idea is to keep the amount of global state as low as possible. Pluto.jl creates a dependency graph between cells: If cell A defines foo, and cell B uses foo, then cell B depends on cell A. Whenever cell A is updated, cell B will automatically be re-evaluated.
(edit: I suppose it's not really global state I'm talking about as much as hidden state left over from overwritten or deleted cells)
For example, I typically create tonnes of code cells when I visualize and try to get a sense of some data. The large majority of cells (probably >80%) are then deleted, and whenever I find a trivial bug in some code, I fix the cell where the bug occured.
But now - which cells had I rerun after fixing the bug? And did any of the run cells depend on some variable in a deleted cell? If so, the notebook will no longer be reproducible when I re-run it? It's impossible to keep track of. So when I use Jupyter, I frequently press the "restart kernel and run all" option. But of course, that is slow. So I need to serialize a lot of data, which is troublesome. Pluto completely circumvents that problem.
In a more complex example where you actually take a variable, do some operations to it, then reassign it, Pluto.jl encourages you to separate that into multiple cells. The reason is each cell marks a distinct node in the dependency graph. If you prefer to use cells, then the notebook can be smarter about what lines actually need to get re-run and what don't.
A downside to using multiple cells is vertical spacing/visual noise. This is something that the package authors are currently thinking about addressing.
Think of it as working with immutable data, because that's essentially what it is. Which has all the pros and cons of that approach (in my opinion a lot more pros, but YMMV).
Yes, that's the best explanation in the end I think. Maybe I'm too used to reuse variables and that's a bad habit I should work on. For example most of my counters are called i.
It completely fixes a huge number of the gripes in the JupyterCon talk I don't like notebooks by Joel Grus.
The primary complaint there is that notebooks have a disconnect between the state of the program and the display of the cells. By using a completely reactive mode the state is no longer hidden. It's more akin to a spreadsheet than a notebook. A number of other complaints are completely circumvented by using a file format that's simply a pure Julia file with clever comments.
Switching to Julia. You can just use PyCall to call all of your old code, so py"\paste" and you're using Pluto is like a 1 minute process. Then you can get fancy later.
You'll also save a lot of effort in future endeavors, IMO.
Remember, once you've switched to Julia, Python is still only a `using PyCall` and `pyimport` away!
The basic Dask-like functionality is in Dagger.jl, we have plans to move out the distributed array functionality out of it and keep just the scheduler in there.
I'm working on a set of functions to work with many DataFrames (or anything) in parallel and do it out of core if possible, it's basically like JuliaDB but with a FileTree abstraction rather than a table abstraction.
reply